payload 1.2.0 → 1.2.2

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 (138) hide show
  1. package/CHANGELOG.md +161 -16
  2. package/components/fields/Array.ts +1 -2
  3. package/components/fields/Blocks.ts +1 -2
  4. package/components/fields/Cell.ts +1 -1
  5. package/components/fields/Checkbox.ts +1 -2
  6. package/components/fields/Code.ts +1 -2
  7. package/components/fields/DateTime.ts +1 -2
  8. package/components/fields/Email.ts +1 -2
  9. package/components/fields/Group.ts +1 -2
  10. package/components/fields/Number.ts +1 -2
  11. package/components/fields/Password.ts +1 -2
  12. package/components/fields/RadioGroup/RadioInput.ts +1 -2
  13. package/components/fields/RadioGroup/index.ts +1 -2
  14. package/components/fields/Relationship.ts +1 -2
  15. package/components/fields/RichText.ts +1 -2
  16. package/components/fields/Row.ts +1 -2
  17. package/components/fields/Select.ts +1 -2
  18. package/components/fields/Text.ts +1 -2
  19. package/components/fields/Textarea.ts +1 -2
  20. package/components/fields/Upload.ts +1 -2
  21. package/components/views/Cell.ts +1 -2
  22. package/components/views/Edit.ts +1 -2
  23. package/components/views/List.ts +1 -2
  24. package/dist/admin/components/elements/ReactSelect/index.js +4 -4
  25. package/dist/admin/components/elements/ReactSelect/types.d.ts +11 -10
  26. package/dist/admin/components/elements/Status/index.js +1 -1
  27. package/dist/admin/components/elements/VersionsCount/index.js +1 -1
  28. package/dist/admin/components/elements/WhereBuilder/Condition/Text/index.js +5 -1
  29. package/dist/admin/components/forms/Form/context.d.ts +15 -0
  30. package/dist/admin/components/forms/Form/context.js +16 -1
  31. package/dist/admin/components/forms/field-types/Blocks/SectionTitle/index.scss +3 -2
  32. package/dist/admin/components/forms/field-types/Blocks/index.js +1 -1
  33. package/dist/admin/components/forms/field-types/Code/Code.js +3 -4
  34. package/dist/admin/components/forms/field-types/Code/index.scss +177 -78
  35. package/dist/admin/components/forms/field-types/Relationship/AddNew/index.js +0 -1
  36. package/dist/admin/components/forms/field-types/Relationship/GetFilterOptions/index.d.ts +11 -0
  37. package/dist/admin/components/forms/field-types/Relationship/GetFilterOptions/index.js +37 -0
  38. package/dist/admin/components/forms/field-types/Relationship/findOptionsByValue.d.ts +8 -0
  39. package/dist/admin/components/forms/field-types/Relationship/findOptionsByValue.js +29 -0
  40. package/dist/admin/components/forms/field-types/Relationship/index.js +89 -139
  41. package/dist/admin/components/forms/field-types/Relationship/optionsReducer.d.ts +2 -2
  42. package/dist/admin/components/forms/field-types/Relationship/optionsReducer.js +2 -29
  43. package/dist/admin/components/forms/field-types/Relationship/types.d.ts +14 -2
  44. package/dist/admin/components/forms/field-types/RichText/elements/link/Element.js +3 -3
  45. package/dist/admin/components/forms/field-types/RichText/elements/link/index.scss +2 -1
  46. package/dist/admin/components/forms/field-types/RichText/elements/upload/Button/index.js +1 -1
  47. package/dist/admin/components/forms/field-types/Row/index.js +1 -1
  48. package/dist/admin/components/forms/field-types/Select/Input.d.ts +2 -2
  49. package/dist/admin/components/forms/field-types/Select/Input.js +13 -3
  50. package/dist/admin/components/forms/field-types/Textarea/Input.js +1 -1
  51. package/dist/admin/components/forms/field-types/Textarea/index.scss +3 -6
  52. package/dist/admin/components/forms/useField/index.d.ts +5 -0
  53. package/dist/admin/components/forms/useField/index.js +5 -0
  54. package/dist/admin/components/utilities/I18n/index.js +1 -1
  55. package/dist/admin/components/views/Account/index.js +6 -1
  56. package/dist/admin/components/views/Global/index.scss +31 -24
  57. package/dist/admin/components/views/Login/index.js +1 -1
  58. package/dist/admin/components/views/Version/RenderFieldsToDiff/fields/Iterable/index.js +1 -1
  59. package/dist/admin/components/views/Version/RenderFieldsToDiff/fields/Nested/index.js +15 -9
  60. package/dist/admin/components/views/Version/RenderFieldsToDiff/fields/Relationship/index.js +5 -2
  61. package/dist/admin/components/views/Version/RenderFieldsToDiff/fields/Select/index.d.ts +5 -0
  62. package/dist/admin/components/views/Version/RenderFieldsToDiff/fields/Select/index.js +34 -0
  63. package/dist/admin/components/views/Version/RenderFieldsToDiff/fields/Select/index.scss +10 -0
  64. package/dist/admin/components/views/Version/RenderFieldsToDiff/fields/Text/index.js +3 -2
  65. package/dist/admin/components/views/Version/RenderFieldsToDiff/fields/index.js +3 -2
  66. package/dist/admin/components/views/Versions/index.js +1 -1
  67. package/dist/admin/components/views/collections/Edit/Default.js +2 -0
  68. package/dist/admin/components/views/collections/Edit/SetStepNav.d.ts +7 -0
  69. package/dist/admin/components/views/collections/Edit/SetStepNav.js +31 -0
  70. package/dist/admin/components/views/collections/Edit/index.js +2 -36
  71. package/dist/admin/components/views/collections/Edit/index.scss +19 -4
  72. package/dist/admin/hooks/usePayloadAPI.js +3 -1
  73. package/dist/collections/buildSchema.js +5 -1
  74. package/dist/collections/config/types.d.ts +16 -3
  75. package/dist/collections/operations/find.js +11 -6
  76. package/dist/collections/operations/findVersions.js +4 -5
  77. package/dist/collections/operations/update.js +8 -9
  78. package/dist/collections/requestHandlers/find.js +4 -3
  79. package/dist/collections/requestHandlers/update.js +3 -3
  80. package/dist/config/schema.js +2 -2
  81. package/dist/config/types.d.ts +269 -6
  82. package/dist/config/types.js +1 -1
  83. package/dist/email/build.js +2 -2
  84. package/dist/express/types.d.ts +26 -2
  85. package/dist/fields/config/sanitize.spec.js +5 -5
  86. package/dist/fields/config/types.d.ts +3 -3
  87. package/dist/fields/hooks/afterRead/relationshipPopulationPromise.js +73 -21
  88. package/dist/fields/hooks/beforeChange/promise.js +7 -1
  89. package/dist/globals/operations/findVersions.js +4 -5
  90. package/dist/globals/operations/update.js +4 -4
  91. package/dist/globals/requestHandlers/update.js +3 -3
  92. package/dist/graphql/schema/fieldToWhereInputSchemaMap.js +7 -7
  93. package/dist/graphql/schema/operators.d.ts +1 -0
  94. package/dist/graphql/schema/operators.js +2 -1
  95. package/dist/mongoose/types.d.ts +3 -3
  96. package/dist/translations/de.json +100 -100
  97. package/dist/translations/en.json +3 -1
  98. package/dist/translations/es.json +1 -1
  99. package/dist/translations/fr.json +1 -1
  100. package/dist/translations/index.d.ts +5 -0
  101. package/dist/translations/it.json +19 -16
  102. package/dist/translations/my.json +1 -1
  103. package/dist/translations/nl.json +1 -1
  104. package/dist/translations/pl.json +1 -1
  105. package/dist/translations/pt.json +1 -1
  106. package/dist/translations/ru.json +1 -1
  107. package/dist/translations/sv.json +1 -1
  108. package/dist/translations/vi.json +1 -1
  109. package/dist/utilities/isNumber.d.ts +1 -0
  110. package/dist/utilities/isNumber.js +8 -0
  111. package/dist/versions/drafts/saveCollectionDraft.js +4 -3
  112. package/dist/versions/drafts/saveGlobalDraft.js +4 -3
  113. package/dist/versions/ensurePublishedCollectionVersion.js +2 -1
  114. package/dist/versions/ensurePublishedGlobalVersion.js +2 -1
  115. package/dist/versions/getLatestCollectionVersion.d.ts +10 -0
  116. package/dist/versions/getLatestCollectionVersion.js +27 -0
  117. package/dist/versions/getLatestGlobalVersion.d.ts +10 -0
  118. package/dist/versions/getLatestGlobalVersion.js +27 -0
  119. package/docs/admin/components.mdx +1 -5
  120. package/docs/authentication/config.mdx +1 -1
  121. package/docs/configuration/globals.mdx +12 -12
  122. package/docs/configuration/i18n.mdx +1 -1
  123. package/docs/fields/array.mdx +14 -14
  124. package/docs/fields/blocks.mdx +1 -1
  125. package/docs/fields/checkbox.mdx +2 -2
  126. package/docs/fields/code.mdx +1 -1
  127. package/docs/fields/date.mdx +1 -1
  128. package/docs/fields/email.mdx +1 -1
  129. package/docs/fields/number.mdx +1 -1
  130. package/docs/fields/radio.mdx +1 -1
  131. package/docs/fields/relationship.mdx +1 -1
  132. package/docs/fields/rich-text.mdx +1 -1
  133. package/docs/fields/select.mdx +2 -2
  134. package/docs/fields/text.mdx +2 -2
  135. package/docs/fields/textarea.mdx +1 -1
  136. package/docs/fields/upload.mdx +51 -17
  137. package/docs/production/preventing-abuse.mdx +6 -6
  138. package/package.json +3 -2
@@ -29,7 +29,12 @@ const AccountView = () => {
29
29
  const collection = collections.find((coll) => coll.slug === adminUser);
30
30
  const { fields } = collection;
31
31
  const collectionPermissions = (_a = permissions === null || permissions === void 0 ? void 0 : permissions.collections) === null || _a === void 0 ? void 0 : _a[adminUser];
32
- const [{ data }] = usePayloadAPI(`${serverURL}${api}/${collection === null || collection === void 0 ? void 0 : collection.slug}/${user === null || user === void 0 ? void 0 : user.id}?depth=0`, { initialParams: { 'fallback-locale': 'null' } });
32
+ const [{ data }] = usePayloadAPI(`${serverURL}${api}/${collection === null || collection === void 0 ? void 0 : collection.slug}/${user === null || user === void 0 ? void 0 : user.id}`, {
33
+ initialParams: {
34
+ 'fallback-locale': 'null',
35
+ depth: 0,
36
+ },
37
+ });
33
38
  const hasSavePermission = (_b = collectionPermissions === null || collectionPermissions === void 0 ? void 0 : collectionPermissions.update) === null || _b === void 0 ? void 0 : _b.permission;
34
39
  const dataToRender = (locationState === null || locationState === void 0 ? void 0 : locationState.data) || data;
35
40
  const apiURL = `${serverURL}${api}/${user.collection}/${data === null || data === void 0 ? void 0 : data.id}`;
@@ -29,17 +29,6 @@
29
29
  margin-top: base(.25);
30
30
  }
31
31
 
32
- &__collection-actions {
33
- list-style: none;
34
- margin: 0;
35
- padding: base(1.5) 0 base(.5);
36
- display: flex;
37
-
38
- li {
39
- margin-right: base(.75);
40
- }
41
- }
42
-
43
32
  &__edit {
44
33
  padding-top: base(1);
45
34
  padding-bottom: base(2);
@@ -74,6 +63,17 @@
74
63
  padding-left: base(1.5);
75
64
  }
76
65
 
66
+ &__sidebar-fields {
67
+ padding-right: $baseline;
68
+ margin-bottom: base(1);
69
+
70
+ .preview-btn {
71
+ display: inline-block;
72
+ margin-top: 0;
73
+ width: calc(50% - #{base(.5)});
74
+ }
75
+ }
76
+
77
77
  &__document-actions {
78
78
  @include blur-bg;
79
79
  position: sticky;
@@ -113,7 +113,6 @@
113
113
 
114
114
  &__api-url {
115
115
  margin-bottom: base(1.5);
116
- padding-right: base(1.5);
117
116
 
118
117
  a {
119
118
  display: block;
@@ -125,10 +124,15 @@
125
124
  &__meta {
126
125
  margin: auto 0 $baseline;
127
126
  padding-top: $baseline;
127
+ padding-right: $baseline;
128
128
  list-style: none;
129
129
 
130
130
  li {
131
131
  margin-bottom: base(.5);
132
+
133
+ &:last-child {
134
+ margin-bottom: 0;
135
+ }
132
136
  }
133
137
  }
134
138
 
@@ -136,7 +140,6 @@
136
140
  color: var(--theme-elevation-400);
137
141
  }
138
142
 
139
- &__collection-actions,
140
143
  &__api-url {
141
144
 
142
145
  a,
@@ -169,6 +172,10 @@
169
172
  height: initial;
170
173
  }
171
174
 
175
+ &__meta {
176
+ border-top: 1px solid var(--theme-elevation-100);
177
+ }
178
+
172
179
  &__form {
173
180
  display: block;
174
181
  }
@@ -190,24 +197,24 @@
190
197
  &__meta,
191
198
  &__sidebar-fields {
192
199
  padding-left: var(--gutter-h);
200
+ padding-right: var(--gutter-h);
193
201
  }
194
202
 
195
- &__api-url {
196
- margin-bottom: base(.5);
197
- }
198
-
199
- &__collection-actions {
200
- border-top: 1px solid var(--theme-elevation-100);
201
- padding: base(1) 0 0 base(1);
202
- order: 1;
203
+ &__sidebar-fields {
204
+ margin-bottom: base(1);
205
+ padding-top: base(1);
203
206
 
204
- li {
205
- margin: 0 base(.5) 0 0;
207
+ .preview-btn {
208
+ width: 100%;
206
209
  }
207
210
  }
208
211
 
212
+ &__api-url {
213
+ margin-bottom: base(.5);
214
+ }
215
+
209
216
  &__sidebar {
210
- padding-bottom: base(4);
217
+ padding-bottom: base(3.5);
211
218
  }
212
219
 
213
220
  &__sidebar-sticky {
@@ -45,7 +45,7 @@ const Login = () => {
45
45
  !collection.auth.disableLocalStrategy && (React.createElement(Form, { disableSuccessStatus: true, waitForAutocomplete: true, onSuccess: onSuccess, method: "post", action: `${serverURL}${api}/${userSlug}/login` },
46
46
  React.createElement(Email, { label: t('general:email'), name: "email", admin: { autoComplete: 'email' }, required: true }),
47
47
  React.createElement(Password, { label: t('general:password'), name: "password", autoComplete: "off", required: true }),
48
- React.createElement(Link, { to: `${admin}/forgot` }, t('forgotPassword')),
48
+ React.createElement(Link, { to: `${admin}/forgot` }, t('forgotPasswordQuestion')),
49
49
  React.createElement(FormSubmit, null, t('login')))),
50
50
  Array.isArray(afterLogin) && afterLogin.map((Component, i) => React.createElement(Component, { key: i }))));
51
51
  };
@@ -16,7 +16,7 @@ const Iterable = ({ version, comparison, permissions, field, locale, locales, fi
16
16
  return (React.createElement("div", { className: baseClass },
17
17
  field.label && (React.createElement(Label, null,
18
18
  locale && (React.createElement("span", { className: `${baseClass}__locale-label` }, locale)),
19
- field.label)),
19
+ getTranslation(field.label, i18n))),
20
20
  maxRows > 0 && (React.createElement(React.Fragment, null, Array.from(Array(maxRows).keys()).map((row, i) => {
21
21
  const versionRow = (version === null || version === void 0 ? void 0 : version[i]) || {};
22
22
  const comparisonRow = (comparison === null || comparison === void 0 ? void 0 : comparison[i]) || {};
@@ -1,15 +1,21 @@
1
1
  import React from 'react';
2
+ import { useTranslation } from 'react-i18next';
2
3
  import RenderFieldsToDiff from '../..';
3
4
  import Label from '../../Label';
5
+ import { getTranslation } from '../../../../../../../utilities/getTranslation';
4
6
  import './index.scss';
5
7
  const baseClass = 'nested-diff';
6
- const Nested = ({ version, comparison, permissions, field, locale, locales, fieldComponents, disableGutter = false, }) => (React.createElement("div", { className: baseClass },
7
- field.label && (React.createElement(Label, null,
8
- locale && (React.createElement("span", { className: `${baseClass}__locale-label` }, locale)),
9
- field.label)),
10
- React.createElement("div", { className: [
11
- `${baseClass}__wrap`,
12
- !disableGutter && `${baseClass}__wrap--gutter`,
13
- ].filter(Boolean).join(' ') },
14
- React.createElement(RenderFieldsToDiff, { locales: locales, version: version, comparison: comparison, fieldPermissions: permissions, fields: field.fields, fieldComponents: fieldComponents }))));
8
+ const Nested = ({ version, comparison, permissions, field, locale, locales, fieldComponents, disableGutter = false, }) => {
9
+ const { i18n } = useTranslation();
10
+ return (React.createElement("div", { className: baseClass },
11
+ field.label && (React.createElement(Label, null,
12
+ locale && (React.createElement("span", { className: `${baseClass}__locale-label` }, locale)),
13
+ getTranslation(field.label, i18n))),
14
+ React.createElement("div", { className: [
15
+ `${baseClass}__wrap`,
16
+ !disableGutter && `${baseClass}__wrap--gutter`,
17
+ ].filter(Boolean)
18
+ .join(' ') },
19
+ React.createElement(RenderFieldsToDiff, { locales: locales, version: version, comparison: comparison, fieldPermissions: permissions, fields: field.fields, fieldComponents: fieldComponents }))));
20
+ };
15
21
  export default Nested;
@@ -1,10 +1,12 @@
1
1
  import React from 'react';
2
2
  import ReactDiffViewer from 'react-diff-viewer';
3
+ import { useTranslation } from 'react-i18next';
3
4
  import { useConfig } from '../../../../../utilities/Config';
4
5
  import { useLocale } from '../../../../../utilities/Locale';
5
6
  import { fieldAffectsData, fieldIsPresentationalOnly } from '../../../../../../../fields/config/types';
6
7
  import Label from '../../Label';
7
8
  import { diffStyles } from '../styles';
9
+ import { getTranslation } from '../../../../../../../utilities/getTranslation';
8
10
  import './index.scss';
9
11
  const baseClass = 'relationship-diff';
10
12
  const generateLabelFromValue = (collections, field, locale, value) => {
@@ -43,10 +45,11 @@ const generateLabelFromValue = (collections, field, locale, value) => {
43
45
  };
44
46
  const Relationship = ({ field, version, comparison }) => {
45
47
  const { collections } = useConfig();
48
+ const { t, i18n } = useTranslation('general');
46
49
  const locale = useLocale();
47
50
  let placeholder = '';
48
51
  if (version === comparison)
49
- placeholder = '[no value]';
52
+ placeholder = `[${t('noValue')}]`;
50
53
  let versionToRender = version;
51
54
  let comparisonToRender = comparison;
52
55
  if (field.hasMany) {
@@ -62,7 +65,7 @@ const Relationship = ({ field, version, comparison }) => {
62
65
  return (React.createElement("div", { className: baseClass },
63
66
  React.createElement(Label, null,
64
67
  locale && (React.createElement("span", { className: `${baseClass}__locale-label` }, locale)),
65
- field.label),
68
+ getTranslation(field.label, i18n)),
66
69
  React.createElement(ReactDiffViewer, { styles: diffStyles, oldValue: typeof comparisonToRender !== 'undefined' ? String(comparisonToRender) : placeholder, newValue: typeof versionToRender !== 'undefined' ? String(versionToRender) : placeholder, splitView: true, hideLineNumbers: true, showDiffOnly: false })));
67
70
  return null;
68
71
  };
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { Props } from '../types';
3
+ import './index.scss';
4
+ declare const Select: React.FC<Props>;
5
+ export default Select;
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer';
3
+ import { useTranslation } from 'react-i18next';
4
+ import Label from '../../Label';
5
+ import { diffStyles } from '../styles';
6
+ import { getTranslation } from '../../../../../../../utilities/getTranslation';
7
+ import './index.scss';
8
+ const baseClass = 'select-diff';
9
+ const getOptionsToRender = (value, options, hasMany) => {
10
+ if (hasMany && Array.isArray(value)) {
11
+ return value.map((val) => options.find((option) => (typeof option === 'string' ? option : option.value) === val));
12
+ }
13
+ return options.find((option) => (typeof option === 'string' ? option : option.value) === value);
14
+ };
15
+ const getTranslatedOptions = (options, i18n) => {
16
+ if (Array.isArray(options)) {
17
+ return options.map((option) => (typeof option === 'string' ? option : getTranslation(option.label, i18n))).join(', ');
18
+ }
19
+ return typeof options === 'string' ? options : getTranslation(options.label, i18n);
20
+ };
21
+ const Select = ({ field, locale, version, comparison, diffMethod }) => {
22
+ let placeholder = '';
23
+ const { t, i18n } = useTranslation('general');
24
+ if (version === comparison)
25
+ placeholder = `[${t('noValue')}]`;
26
+ const comparisonToRender = typeof comparison !== 'undefined' ? getTranslatedOptions(getOptionsToRender(comparison, field.options, field.hasMany), i18n) : placeholder;
27
+ const versionToRender = typeof version !== 'undefined' ? getTranslatedOptions(getOptionsToRender(version, field.options, field.hasMany), i18n) : placeholder;
28
+ return (React.createElement("div", { className: baseClass },
29
+ React.createElement(Label, null,
30
+ locale && (React.createElement("span", { className: `${baseClass}__locale-label` }, locale)),
31
+ getTranslation(field.label, i18n)),
32
+ React.createElement(ReactDiffViewer, { styles: diffStyles, compareMethod: DiffMethod[diffMethod], oldValue: comparisonToRender, newValue: typeof versionToRender !== 'undefined' ? versionToRender : placeholder, splitView: true, hideLineNumbers: true, showDiffOnly: false })));
33
+ };
34
+ export default Select;
@@ -0,0 +1,10 @@
1
+ @import '../../../../../../scss/styles.scss';
2
+
3
+ .select-diff {
4
+ &__locale-label {
5
+ margin-right: base(.25);
6
+ background: var(--theme-elevation-100);
7
+ padding: base(.25);
8
+ border-radius: $style-radius-m;
9
+ }
10
+ }
@@ -3,11 +3,12 @@ import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import Label from '../../Label';
5
5
  import { diffStyles } from '../styles';
6
+ import { getTranslation } from '../../../../../../../utilities/getTranslation';
6
7
  import './index.scss';
7
8
  const baseClass = 'text-diff';
8
9
  const Text = ({ field, locale, version, comparison, isRichText = false, diffMethod }) => {
9
10
  let placeholder = '';
10
- const { t } = useTranslation('general');
11
+ const { t, i18n } = useTranslation('general');
11
12
  if (version === comparison)
12
13
  placeholder = `[${t('noValue')}]`;
13
14
  let versionToRender = version;
@@ -21,7 +22,7 @@ const Text = ({ field, locale, version, comparison, isRichText = false, diffMeth
21
22
  return (React.createElement("div", { className: baseClass },
22
23
  React.createElement(Label, null,
23
24
  locale && (React.createElement("span", { className: `${baseClass}__locale-label` }, locale)),
24
- field.label),
25
+ getTranslation(field.label, i18n)),
25
26
  React.createElement(ReactDiffViewer, { styles: diffStyles, compareMethod: DiffMethod[diffMethod], oldValue: typeof comparisonToRender !== 'undefined' ? String(comparisonToRender) : placeholder, newValue: typeof versionToRender !== 'undefined' ? String(versionToRender) : placeholder, splitView: true, hideLineNumbers: true, showDiffOnly: false })));
26
27
  };
27
28
  export default Text;
@@ -3,6 +3,7 @@ import Nested from './Nested';
3
3
  import Iterable from './Iterable';
4
4
  import Relationship from './Relationship';
5
5
  import Tabs from './Tabs';
6
+ import Select from './Select';
6
7
  export default {
7
8
  text: Text,
8
9
  textarea: Text,
@@ -10,14 +11,14 @@ export default {
10
11
  email: Text,
11
12
  code: Text,
12
13
  checkbox: Text,
13
- radio: Text,
14
+ radio: Select,
14
15
  row: Nested,
15
16
  collapsible: Nested,
16
17
  group: Nested,
17
18
  array: Iterable,
18
19
  blocks: Iterable,
19
20
  date: Text,
20
- select: Text,
21
+ select: Select,
21
22
  richText: Text,
22
23
  relationship: Relationship,
23
24
  upload: Relationship,
@@ -148,7 +148,7 @@ const Versions = ({ collection, global }) => {
148
148
  React.createElement(Eyebrow, null),
149
149
  React.createElement(Gutter, { className: `${baseClass}__wrap` },
150
150
  React.createElement("header", { className: `${baseClass}__header` },
151
- React.createElement("div", { className: `${baseClass}__intro` }, "Showing versions for:"),
151
+ React.createElement("div", { className: `${baseClass}__intro` }, t('showingVersionsFor')),
152
152
  useIDLabel && (React.createElement(IDLabel, { id: doc === null || doc === void 0 ? void 0 : doc.id })),
153
153
  !useIDLabel && (React.createElement("h1", null, heading))),
154
154
  isLoadingVersions && (React.createElement(Loading, null)),
@@ -27,6 +27,7 @@ import { useDocumentInfo } from '../../../utilities/DocumentInfo';
27
27
  import { OperationContext } from '../../../utilities/OperationProvider';
28
28
  import { Gutter } from '../../../elements/Gutter';
29
29
  import { getTranslation } from '../../../../../utilities/getTranslation';
30
+ import { SetStepNav } from './SetStepNav';
30
31
  import './index.scss';
31
32
  const baseClass = 'collection-edit';
32
33
  const DefaultEditView = (props) => {
@@ -45,6 +46,7 @@ const DefaultEditView = (props) => {
45
46
  isLoading && (React.createElement(Loading, null)),
46
47
  !isLoading && (React.createElement(OperationContext.Provider, { value: operation },
47
48
  React.createElement(Form, { className: `${baseClass}__form`, method: id ? 'patch' : 'post', action: action, onSuccess: onSave, disabled: !hasSavePermission, initialState: initialState },
49
+ React.createElement(SetStepNav, { collection: collection, isEditing: isEditing, id: data.id }),
48
50
  React.createElement("div", { className: `${baseClass}__main` },
49
51
  React.createElement(Meta, { title: `${isEditing ? t('editing') : t('creating')} - ${getTranslation(collection.labels.singular, i18n)}`, description: `${isEditing ? t('editing') : t('creating')} - ${getTranslation(collection.labels.singular, i18n)}`, keywords: `${getTranslation(collection.labels.singular, i18n)}, Payload, CMS` }),
50
52
  !disableEyebrow && (React.createElement(Eyebrow, null)),
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" />
2
+ import { SanitizedCollectionConfig } from '../../../../../collections/config/types';
3
+ export declare const SetStepNav: React.FC<{
4
+ collection: SanitizedCollectionConfig;
5
+ isEditing: boolean;
6
+ id: string;
7
+ }>;
@@ -0,0 +1,31 @@
1
+ import { useEffect } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { getTranslation } from '../../../../../utilities/getTranslation';
4
+ import useTitle from '../../../../hooks/useTitle';
5
+ import { useStepNav } from '../../../elements/StepNav';
6
+ import { useConfig } from '../../../utilities/Config';
7
+ export const SetStepNav = ({ collection, isEditing, id }) => {
8
+ const { slug, labels: { plural: pluralLabel, }, admin: { useAsTitle, }, } = collection;
9
+ const { setStepNav } = useStepNav();
10
+ const { t, i18n } = useTranslation('general');
11
+ const { routes: { admin } } = useConfig();
12
+ const title = useTitle(useAsTitle);
13
+ useEffect(() => {
14
+ const nav = [{
15
+ url: `${admin}/collections/${slug}`,
16
+ label: getTranslation(pluralLabel, i18n),
17
+ }];
18
+ if (isEditing) {
19
+ nav.push({
20
+ label: (useAsTitle && useAsTitle !== 'id') ? title || `[${t('untitled')}]` : id,
21
+ });
22
+ }
23
+ else {
24
+ nav.push({
25
+ label: t('createNew'),
26
+ });
27
+ }
28
+ setStepNav(nav);
29
+ }, [setStepNav, isEditing, pluralLabel, id, slug, useAsTitle, admin, t, i18n, title]);
30
+ return null;
31
+ };
@@ -3,7 +3,6 @@ import { Redirect, useRouteMatch, useHistory, useLocation } from 'react-router-d
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { useConfig } from '../../../utilities/Config';
5
5
  import { useAuth } from '../../../utilities/Auth';
6
- import { useStepNav } from '../../../elements/StepNav';
7
6
  import usePayloadAPI from '../../../../hooks/usePayloadAPI';
8
7
  import RenderCustomComponent from '../../../utilities/RenderCustomComponent';
9
8
  import DefaultEdit from './Default';
@@ -13,11 +12,10 @@ import { useLocale } from '../../../utilities/Locale';
13
12
  import { useDocumentInfo } from '../../../utilities/DocumentInfo';
14
13
  import { usePreferences } from '../../../utilities/Preferences';
15
14
  import { EditDepthContext } from '../../../utilities/EditDepth';
16
- import { getTranslation } from '../../../../../utilities/getTranslation';
17
15
  const EditView = (props) => {
18
16
  var _a, _b, _c;
19
17
  const { collection: incomingCollection, isEditing } = props;
20
- const { slug, labels: { plural: pluralLabel, }, admin: { useAsTitle, components: { views: { Edit: CustomEdit, } = {}, } = {}, } = {}, } = incomingCollection;
18
+ const { slug, admin: { components: { views: { Edit: CustomEdit, } = {}, } = {}, } = {}, } = incomingCollection;
21
19
  const [fields] = useState(() => formatFields(incomingCollection, isEditing));
22
20
  const [collection] = useState(() => ({ ...incomingCollection, fields }));
23
21
  const [redirect, setRedirect] = useState();
@@ -26,12 +24,11 @@ const EditView = (props) => {
26
24
  const { params: { id } = {} } = useRouteMatch();
27
25
  const { state: locationState } = useLocation();
28
26
  const history = useHistory();
29
- const { setStepNav } = useStepNav();
30
27
  const [initialState, setInitialState] = useState();
31
28
  const { permissions, user } = useAuth();
32
29
  const { getVersions, preferencesKey } = useDocumentInfo();
33
30
  const { getPreference } = usePreferences();
34
- const { t, i18n } = useTranslation('general');
31
+ const { t } = useTranslation('general');
35
32
  const onSave = useCallback(async (json) => {
36
33
  var _a;
37
34
  getVersions();
@@ -45,37 +42,6 @@ const EditView = (props) => {
45
42
  }, [admin, collection, isEditing, getVersions, user, id, t, locale]);
46
43
  const [{ data, isLoading: isLoadingDocument, isError }] = usePayloadAPI((isEditing ? `${serverURL}${api}/${slug}/${id}` : null), { initialParams: { 'fallback-locale': 'null', depth: 0, draft: 'true' } });
47
44
  const dataToRender = (locationState === null || locationState === void 0 ? void 0 : locationState.data) || data;
48
- useEffect(() => {
49
- const nav = [{
50
- url: `${admin}/collections/${slug}`,
51
- label: getTranslation(pluralLabel, i18n),
52
- }];
53
- if (isEditing) {
54
- let label = '';
55
- if (dataToRender) {
56
- if (useAsTitle) {
57
- if (dataToRender[useAsTitle]) {
58
- label = dataToRender[useAsTitle];
59
- }
60
- else {
61
- label = `[${t('untitled')}]`;
62
- }
63
- }
64
- else {
65
- label = dataToRender.id;
66
- }
67
- }
68
- nav.push({
69
- label,
70
- });
71
- }
72
- else {
73
- nav.push({
74
- label: t('createNew'),
75
- });
76
- }
77
- setStepNav(nav);
78
- }, [setStepNav, isEditing, pluralLabel, dataToRender, slug, useAsTitle, admin, t, i18n]);
79
45
  useEffect(() => {
80
46
  if (isLoadingDocument) {
81
47
  return;
@@ -108,7 +108,6 @@
108
108
 
109
109
  &__api-url {
110
110
  margin-bottom: base(1.5);
111
- padding-right: base(1.5);
112
111
 
113
112
  a {
114
113
  display: block;
@@ -119,6 +118,7 @@
119
118
 
120
119
  &__sidebar-fields {
121
120
  padding-right: $baseline;
121
+ margin-bottom: base(1);
122
122
 
123
123
  .preview-btn {
124
124
  display: inline-block;
@@ -130,10 +130,15 @@
130
130
  &__meta {
131
131
  margin: auto 0 $baseline 0;
132
132
  padding-top: $baseline;
133
+ padding-right: $baseline;
133
134
  list-style: none;
134
135
 
135
136
  li {
136
137
  margin-bottom: base(.5);
138
+
139
+ &:last-child {
140
+ margin-bottom: 0;
141
+ }
137
142
  }
138
143
  }
139
144
 
@@ -174,6 +179,11 @@
174
179
  height: initial;
175
180
  }
176
181
 
182
+ &__meta {
183
+ border-top: 1px solid var(--theme-elevation-100);
184
+ padding-right: var(--gutter-h);
185
+ }
186
+
177
187
  &__form {
178
188
  display: block;
179
189
  }
@@ -196,9 +206,14 @@
196
206
  &__meta,
197
207
  &__sidebar-fields {
198
208
  padding-left: var(--gutter-h);
209
+ padding-right: var(--gutter-h);
199
210
  }
200
211
 
201
212
  &__sidebar-fields {
213
+ margin-bottom: base(1);
214
+ padding-top: base(1);
215
+ padding-right: var(--gutter-h);
216
+
202
217
  .preview-btn {
203
218
  width: 100%;
204
219
  }
@@ -206,7 +221,7 @@
206
221
 
207
222
  &__collection-actions {
208
223
  border-top: 1px solid var(--theme-elevation-100);
209
- padding: base(1) 0 0 base(1);
224
+ padding: base(1) 0 0 var(--gutter-h);
210
225
  order: 1;
211
226
 
212
227
  li {
@@ -215,7 +230,7 @@
215
230
  }
216
231
 
217
232
  &__sidebar {
218
- padding-bottom: base(4);
233
+ padding-bottom: base(3.5);
219
234
  }
220
235
  }
221
- }
236
+ }
@@ -14,13 +14,15 @@ const usePayloadAPI = (url, options = {}) => {
14
14
  const search = queryString.stringify({
15
15
  locale,
16
16
  ...(typeof params === 'object' ? params : {}),
17
+ }, {
18
+ addQueryPrefix: true,
17
19
  });
18
20
  useEffect(() => {
19
21
  const fetchData = async () => {
20
22
  setIsError(false);
21
23
  setIsLoading(true);
22
24
  try {
23
- const response = await requests.get(`${url}?${search}`, {
25
+ const response = await requests.get(`${url}${search}`, {
24
26
  headers: {
25
27
  'Accept-Language': i18n.language,
26
28
  },
@@ -12,9 +12,13 @@ const buildCollectionSchema = (collection, config, schemaOptions = {}) => {
12
12
  options: { timestamps: collection.timestamps !== false, ...schemaOptions },
13
13
  indexSortableFields: config.indexSortableFields,
14
14
  });
15
+ if (config.indexSortableFields && collection.timestamps !== false) {
16
+ schema.index({ updatedAt: 1 });
17
+ schema.index({ createdAt: 1 });
18
+ }
15
19
  schema.plugin(mongoose_paginate_v2_1.default, { useEstimatedCount: true })
16
20
  .plugin(buildQuery_1.default);
17
21
  return schema;
18
22
  };
19
23
  exports.default = buildCollectionSchema;
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRTY2hlbWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29sbGVjdGlvbnMvYnVpbGRTY2hlbWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxnRkFBNEM7QUFHNUMsd0VBQXNEO0FBQ3RELDBFQUFrRDtBQUdsRCxNQUFNLHFCQUFxQixHQUFHLENBQUMsVUFBcUMsRUFBRSxNQUF1QixFQUFFLGFBQWEsR0FBRyxFQUFFLEVBQVUsRUFBRTtJQUMzSCxNQUFNLE1BQU0sR0FBRyxJQUFBLHFCQUFXLEVBQ3hCLE1BQU0sRUFDTixVQUFVLENBQUMsTUFBTSxFQUNqQjtRQUNFLGFBQWEsRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFBLFVBQVUsYUFBVixVQUFVLHVCQUFWLFVBQVUsQ0FBRSxRQUFRLENBQUEsS0FBSyxRQUFRLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFDOUYsT0FBTyxFQUFFLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxVQUFVLEtBQUssS0FBSyxFQUFFLEdBQUcsYUFBYSxFQUFFO1FBQzFFLG1CQUFtQixFQUFFLE1BQU0sQ0FBQyxtQkFBbUI7S0FDaEQsQ0FDRixDQUFDO0lBRUYsTUFBTSxDQUFDLE1BQU0sQ0FBQyw4QkFBUSxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsSUFBSSxFQUFFLENBQUM7U0FDakQsTUFBTSxDQUFDLG9CQUFnQixDQUFDLENBQUM7SUFFNUIsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyxDQUFDO0FBRUYsa0JBQWUscUJBQXFCLENBQUMifQ==
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRTY2hlbWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29sbGVjdGlvbnMvYnVpbGRTY2hlbWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxnRkFBNEM7QUFHNUMsd0VBQXNEO0FBQ3RELDBFQUFrRDtBQUdsRCxNQUFNLHFCQUFxQixHQUFHLENBQUMsVUFBcUMsRUFBRSxNQUF1QixFQUFFLGFBQWEsR0FBRyxFQUFFLEVBQVUsRUFBRTtJQUMzSCxNQUFNLE1BQU0sR0FBRyxJQUFBLHFCQUFXLEVBQ3hCLE1BQU0sRUFDTixVQUFVLENBQUMsTUFBTSxFQUNqQjtRQUNFLGFBQWEsRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFBLFVBQVUsYUFBVixVQUFVLHVCQUFWLFVBQVUsQ0FBRSxRQUFRLENBQUEsS0FBSyxRQUFRLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFDOUYsT0FBTyxFQUFFLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxVQUFVLEtBQUssS0FBSyxFQUFFLEdBQUcsYUFBYSxFQUFFO1FBQzFFLG1CQUFtQixFQUFFLE1BQU0sQ0FBQyxtQkFBbUI7S0FDaEQsQ0FDRixDQUFDO0lBRUYsSUFBSSxNQUFNLENBQUMsbUJBQW1CLElBQUksVUFBVSxDQUFDLFVBQVUsS0FBSyxLQUFLLEVBQUU7UUFDakUsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztLQUNoQztJQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsOEJBQVEsRUFBRSxFQUFFLGlCQUFpQixFQUFFLElBQUksRUFBRSxDQUFDO1NBQ2pELE1BQU0sQ0FBQyxvQkFBZ0IsQ0FBQyxDQUFDO0lBRTVCLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMsQ0FBQztBQUVGLGtCQUFlLHFCQUFxQixDQUFDIn0=
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { DeepRequired } from 'ts-essentials';
3
- import { PaginateModel } from 'mongoose';
3
+ import { Model, PaginateModel } from 'mongoose';
4
4
  import { GraphQLInputObjectType, GraphQLNonNull, GraphQLObjectType } from 'graphql';
5
5
  import { Response } from 'express';
6
6
  import { Access, GeneratePreviewURL, EntityDescription, Endpoint } from '../../config/types';
@@ -14,7 +14,7 @@ interface PassportLocalModel {
14
14
  register: Register;
15
15
  authenticate: any;
16
16
  }
17
- export interface CollectionModel extends PaginateModel<any>, PassportLocalModel {
17
+ export interface CollectionModel extends Model<any>, PaginateModel<any>, PassportLocalModel {
18
18
  buildQuery: (query: unknown, locale?: string) => Record<string, unknown>;
19
19
  }
20
20
  export interface AuthCollectionModel extends CollectionModel {
@@ -177,6 +177,7 @@ export declare type CollectionAdminOptions = {
177
177
  */
178
178
  preview?: GeneratePreviewURL;
179
179
  };
180
+ /** Manage all aspects of a data collection */
180
181
  export declare type CollectionConfig = {
181
182
  slug: string;
182
183
  /**
@@ -250,10 +251,22 @@ export declare type CollectionConfig = {
250
251
  */
251
252
  auth?: IncomingAuthType | boolean;
252
253
  /**
253
- * Upload options
254
+ * Customize the handling of incoming file uploads
255
+ *
256
+ * @default false // disable uploads
254
257
  */
255
258
  upload?: IncomingUploadType | boolean;
259
+ /**
260
+ * Customize the handling of incoming file uploads
261
+ *
262
+ * @default false // disable versioning
263
+ */
256
264
  versions?: IncomingCollectionVersions | boolean;
265
+ /**
266
+ * Add `createdAt` and `updatedAt` fields
267
+ *
268
+ * @default true
269
+ */
257
270
  timestamps?: boolean;
258
271
  };
259
272
  export interface SanitizedCollectionConfig extends Omit<DeepRequired<CollectionConfig>, 'auth' | 'upload' | 'fields' | 'versions'> {