@strapi/admin 4.5.0-alpha.0 → 4.5.0-beta.0

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 (191) hide show
  1. package/admin/src/StrapiApp.js +4 -12
  2. package/admin/src/components/Providers/index.js +14 -10
  3. package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +24 -0
  4. package/admin/src/content-manager/components/DynamicTable/TableRows/index.js +20 -15
  5. package/admin/src/content-manager/components/DynamicZone/components/Component/index.js +19 -9
  6. package/admin/src/content-manager/components/EditViewDataManagerProvider/index.js +50 -3
  7. package/admin/src/content-manager/components/EditViewDataManagerProvider/reducer.js +50 -9
  8. package/admin/src/content-manager/components/FieldTypeIcon/index.js +31 -1
  9. package/admin/src/content-manager/components/Inputs/index.js +36 -14
  10. package/admin/src/content-manager/components/NonRepeatableComponent/index.js +2 -0
  11. package/admin/src/content-manager/components/RelationInput/RelationInput.js +95 -32
  12. package/admin/src/content-manager/components/RelationInput/components/RelationItem.js +2 -2
  13. package/admin/src/content-manager/components/RelationInput/constants.js +1 -1
  14. package/admin/src/content-manager/components/RelationInputDataManager/RelationInputDataManager.js +33 -22
  15. package/admin/src/content-manager/components/RelationInputDataManager/utils/index.js +1 -0
  16. package/admin/src/content-manager/components/RelationInputDataManager/utils/normalizeRelations.js +10 -3
  17. package/admin/src/content-manager/components/RelationInputDataManager/utils/normalizeSearchResults.js +12 -0
  18. package/admin/src/content-manager/components/RelationInputDataManager/utils/select.js +34 -11
  19. package/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +5 -0
  20. package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +23 -0
  21. package/admin/src/content-manager/hooks/useRelation/useRelation.js +17 -9
  22. package/admin/src/content-manager/pages/EditSettingsView/components/FormModal.js +7 -2
  23. package/admin/src/content-manager/pages/EditSettingsView/index.js +2 -1
  24. package/admin/src/content-manager/pages/EditView/Header/index.js +118 -50
  25. package/admin/src/content-manager/pages/EditView/Header/utils/select.js +4 -0
  26. package/admin/src/content-manager/pages/EditView/index.js +102 -93
  27. package/admin/src/content-manager/pages/ListView/index.js +24 -15
  28. package/admin/src/content-manager/pages/ListView/utils/buildQueryString.js +14 -2
  29. package/admin/src/contexts/ApiTokenPermissions/index.js +24 -0
  30. package/admin/src/core/apis/CustomFields.js +80 -0
  31. package/admin/src/core/apis/index.js +1 -0
  32. package/admin/src/hooks/index.js +1 -0
  33. package/admin/src/hooks/useRegenerate/index.js +34 -0
  34. package/admin/src/pages/HomePage/SocialLinks.js +1 -1
  35. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ActionBoundRoutes/index.js +56 -0
  36. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/getMethodColor.js +41 -0
  37. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/BoundRoute/index.js +72 -0
  38. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/CheckBoxWrapper.js +30 -0
  39. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +150 -0
  40. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/ContenTypesSection/index.js +37 -0
  41. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormApiTokenContainer/index.js +254 -0
  42. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormBody/index.js +77 -0
  43. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormHead/index.js +85 -0
  44. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Permissions/index.js +40 -0
  45. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Regenerate/index.js +68 -0
  46. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +215 -197
  47. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/init.js +13 -0
  48. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/reducer.js +72 -0
  49. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/getDateOfExpiration.js +16 -0
  50. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/index.js +5 -0
  51. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/schema.js +2 -1
  52. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/utils/transformPermissionsData.js +36 -0
  53. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DefaultButton/index.js +63 -0
  54. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/DeleteButton/index.js +1 -0
  55. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/ReadButton/index.js +19 -0
  56. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js +3 -36
  57. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +13 -11
  58. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +3 -2
  59. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/utils/tableHeaders.js +8 -8
  60. package/admin/src/pages/SettingsPage/pages/ApiTokens/ProtectedEditView/index.js +1 -1
  61. package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/index.js +2 -2
  62. package/admin/src/permissions/defaultPermissions.js +2 -6
  63. package/admin/src/translations/ca.json +3 -1
  64. package/admin/src/translations/de.json +4 -1
  65. package/admin/src/translations/dk.json +3 -0
  66. package/admin/src/translations/en.json +22 -1
  67. package/admin/src/translations/es.json +156 -157
  68. package/admin/src/translations/fr.json +3 -0
  69. package/admin/src/translations/gu.json +608 -606
  70. package/admin/src/translations/hi.json +689 -687
  71. package/admin/src/translations/hu.json +2 -0
  72. package/admin/src/translations/id.json +2 -0
  73. package/admin/src/translations/it.json +2 -0
  74. package/admin/src/translations/ja.json +2 -0
  75. package/admin/src/translations/ko.json +2 -0
  76. package/admin/src/translations/ml.json +689 -687
  77. package/admin/src/translations/nl.json +3 -0
  78. package/admin/src/translations/pl.json +2 -0
  79. package/admin/src/translations/pt-BR.json +3 -0
  80. package/admin/src/translations/ru.json +489 -491
  81. package/admin/src/translations/sa.json +85 -82
  82. package/admin/src/translations/sk.json +3 -0
  83. package/admin/src/translations/sv.json +3 -0
  84. package/admin/src/translations/zh-Hans.json +4 -1
  85. package/admin/src/translations/zh.json +3 -0
  86. package/build/1856.d8f13391.chunk.js +173 -0
  87. package/build/{9311.7cc03f29.chunk.js → 1939.e3c87653.chunk.js} +108 -291
  88. package/build/{2077.c935ee42.chunk.js → 2077.31a2d91e.chunk.js} +4 -4
  89. package/build/{2912.a015078a.chunk.js → 2912.ab68a736.chunk.js} +8 -8
  90. package/build/4318.7d167b58.chunk.js +30 -0
  91. package/build/4715.44b1ef9b.chunk.js +386 -0
  92. package/build/{4982.05eda880.chunk.js → 4982.c2a311b7.chunk.js} +9 -9
  93. package/build/7379.d246dd38.chunk.js +1 -0
  94. package/build/{7841.91f793dc.chunk.js → 7841.4b67af3f.chunk.js} +8 -8
  95. package/build/{7866.1201afbd.chunk.js → 7866.5fbeb7e5.chunk.js} +10 -10
  96. package/build/{8380.8789ff76.chunk.js → 8380.9b53a31d.chunk.js} +7 -7
  97. package/build/{8549.133c4473.chunk.js → 8549.cf10b5d1.chunk.js} +4 -4
  98. package/build/8738.a30a2160.chunk.js +461 -0
  99. package/build/{9066.08049eb1.chunk.js → 9066.26faf397.chunk.js} +4 -4
  100. package/build/{9166.037339e0.chunk.js → 9166.8fcb3019.chunk.js} +5 -5
  101. package/build/{9420.43a86e7c.chunk.js → 9420.0fe11290.chunk.js} +6 -6
  102. package/build/962.8651ba3f.chunk.js +184 -0
  103. package/build/Admin-authenticatedApp.883449a5.chunk.js +80 -0
  104. package/build/{Admin_homePage.118926e0.chunk.js → Admin_homePage.4b2be829.chunk.js} +2 -2
  105. package/build/{Admin_profilePage.9d50ac44.chunk.js → Admin_profilePage.da32abbc.chunk.js} +1 -1
  106. package/build/{Admin_settingsPage.98a711e5.chunk.js → Admin_settingsPage.98e2a62b.chunk.js} +16 -16
  107. package/build/admin-app.a61d5c2e.chunk.js +112 -0
  108. package/build/admin-edit-roles-page.4dd6bcb9.chunk.js +1 -0
  109. package/build/{admin-users.97a08630.chunk.js → admin-users.d71f198a.chunk.js} +3 -3
  110. package/build/api-tokens-create-page.93dd0689.chunk.js +1 -0
  111. package/build/api-tokens-edit-page.b0adac81.chunk.js +1 -0
  112. package/build/api-tokens-list-page.bb36535f.chunk.js +16 -0
  113. package/build/{ca-json.a16899ae.chunk.js → ca-json.82df6eab.chunk.js} +1 -1
  114. package/build/content-manager.933dc286.chunk.js +1201 -0
  115. package/build/content-type-builder-list-view.5b3cd768.chunk.js +194 -0
  116. package/build/content-type-builder-translation-en-json.f985c9c4.chunk.js +1 -0
  117. package/build/content-type-builder.a6e29716.chunk.js +145 -0
  118. package/build/{de-json.aa6026b3.chunk.js → de-json.0ad554eb.chunk.js} +1 -1
  119. package/build/{dk-json.fac2bcfb.chunk.js → dk-json.e195ea1a.chunk.js} +1 -1
  120. package/build/{email-settings-page.64037147.chunk.js → email-settings-page.bfe6227f.chunk.js} +4 -4
  121. package/build/en-json.1889403c.chunk.js +1 -0
  122. package/build/{es-json.d672e181.chunk.js → es-json.09f80f6e.chunk.js} +1 -1
  123. package/build/{fr-json.71a16175.chunk.js → fr-json.606d056b.chunk.js} +1 -1
  124. package/build/{gu-json.ca345cd1.chunk.js → gu-json.9881264f.chunk.js} +1 -1
  125. package/build/{hi-json.50c7e6d4.chunk.js → hi-json.83dcf48f.chunk.js} +1 -1
  126. package/build/{hu-json.e0521dcc.chunk.js → hu-json.6f328bce.chunk.js} +1 -1
  127. package/build/{i18n-settings-page.0b73785d.chunk.js → i18n-settings-page.18166125.chunk.js} +4 -4
  128. package/build/{id-json.4b1ff8d6.chunk.js → id-json.1f3c4303.chunk.js} +1 -1
  129. package/build/index.html +1 -1
  130. package/build/{it-json.86bac220.chunk.js → it-json.494ac432.chunk.js} +1 -1
  131. package/build/{ja-json.4e44e36b.chunk.js → ja-json.6f262117.chunk.js} +1 -1
  132. package/build/{ko-json.1003756e.chunk.js → ko-json.36dc3b9a.chunk.js} +1 -1
  133. package/build/main.63e7ea0a.js +9338 -0
  134. package/build/{ml-json.c7774425.chunk.js → ml-json.9566bf9a.chunk.js} +1 -1
  135. package/build/{nl-json.f58ea235.chunk.js → nl-json.94c3a289.chunk.js} +1 -1
  136. package/build/{pl-json.fed96aba.chunk.js → pl-json.ccc6ef23.chunk.js} +1 -1
  137. package/build/{pt-BR-json.073799ab.chunk.js → pt-BR-json.744f024d.chunk.js} +1 -1
  138. package/build/{ru-json.7ad2cbbf.chunk.js → ru-json.d22ea13c.chunk.js} +1 -1
  139. package/build/{runtime~main.feeac6d3.js → runtime~main.3a5e1b07.js} +1 -1
  140. package/build/{sa-json.f0f704f0.chunk.js → sa-json.8fb1c04d.chunk.js} +1 -1
  141. package/build/{sk-json.a848961b.chunk.js → sk-json.6c7335d4.chunk.js} +1 -1
  142. package/build/sso-settings-page.9ceb0140.chunk.js +1 -0
  143. package/build/{sv-json.b038acbe.chunk.js → sv-json.2e589a7d.chunk.js} +1 -1
  144. package/build/{upload-settings.80ff0974.chunk.js → upload-settings.3d613216.chunk.js} +4 -4
  145. package/build/{upload-translation-en-json.004a86c1.chunk.js → upload-translation-en-json.86da7b0a.chunk.js} +1 -1
  146. package/build/{users-advanced-settings-page.a02f4806.chunk.js → users-advanced-settings-page.f4051d92.chunk.js} +4 -4
  147. package/build/{webhook-edit-page.d2ea3351.chunk.js → webhook-edit-page.9e46fc3f.chunk.js} +1 -1
  148. package/build/{webhook-list-page.2775a683.chunk.js → webhook-list-page.a712ae40.chunk.js} +4 -4
  149. package/build/{zh-Hans-json.03d2bda1.chunk.js → zh-Hans-json.a4d7dc69.chunk.js} +1 -1
  150. package/build/{zh-json.3d0cc664.chunk.js → zh-json.66aa2ae1.chunk.js} +1 -1
  151. package/ee/server/controllers/user.js +5 -3
  152. package/package.json +9 -8
  153. package/server/bootstrap.js +19 -1
  154. package/server/config/admin-actions.js +20 -0
  155. package/server/content-types/api-token-permission.js +36 -0
  156. package/server/content-types/api-token.js +25 -1
  157. package/server/content-types/index.js +1 -0
  158. package/server/controllers/admin.js +3 -0
  159. package/server/controllers/api-token.js +24 -1
  160. package/server/controllers/content-api.js +15 -0
  161. package/server/controllers/index.js +1 -0
  162. package/server/controllers/user.js +3 -2
  163. package/server/routes/api-tokens.js +11 -0
  164. package/server/routes/content-api.js +20 -0
  165. package/server/routes/index.js +2 -0
  166. package/server/services/api-token.js +309 -29
  167. package/server/services/constants.js +10 -0
  168. package/server/services/permission/engine.js +36 -226
  169. package/server/services/permission.js +4 -1
  170. package/server/strategies/admin.js +7 -1
  171. package/server/strategies/api-token.js +72 -11
  172. package/server/validation/api-tokens.js +12 -2
  173. package/utils/get-custom-app-config-file.js +5 -0
  174. package/build/1856.47226450.chunk.js +0 -173
  175. package/build/4715.58cd558f.chunk.js +0 -387
  176. package/build/7098.40dcd7bf.chunk.js +0 -1
  177. package/build/8851.e4ac62f2.chunk.js +0 -158
  178. package/build/Admin-authenticatedApp.e39f36c9.chunk.js +0 -80
  179. package/build/admin-app.4f7618a9.chunk.js +0 -112
  180. package/build/admin-edit-roles-page.554ba3fa.chunk.js +0 -1
  181. package/build/api-tokens-create-page.4c262d6e.chunk.js +0 -1
  182. package/build/api-tokens-edit-page.10a9d368.chunk.js +0 -1
  183. package/build/api-tokens-list-page.442c9f3c.chunk.js +0 -15
  184. package/build/content-manager.7d57c9d1.chunk.js +0 -1200
  185. package/build/content-type-builder-list-view.8cc534e0.chunk.js +0 -194
  186. package/build/content-type-builder-translation-en-json.201bfb78.chunk.js +0 -1
  187. package/build/content-type-builder.684df7a4.chunk.js +0 -142
  188. package/build/en-json.0c69c7d7.chunk.js +0 -1
  189. package/build/main.b47db1a3.js +0 -9337
  190. package/build/sso-settings-page.445184e0.chunk.js +0 -1
  191. package/server/services/permission/engine-hooks.js +0 -82
@@ -26,7 +26,7 @@ const HeaderContainer = styled(Flex)`
26
26
  }
27
27
  `;
28
28
 
29
- const FormModal = ({ onToggle, onMetaChange, onSizeChange, onSubmit, type }) => {
29
+ const FormModal = ({ onToggle, onMetaChange, onSizeChange, onSubmit, type, customFieldUid }) => {
30
30
  const { selectedField } = useLayoutDnd();
31
31
  const { formatMessage } = useIntl();
32
32
 
@@ -47,7 +47,7 @@ const FormModal = ({ onToggle, onMetaChange, onSizeChange, onSubmit, type }) =>
47
47
  <form onSubmit={onSubmit}>
48
48
  <ModalHeader>
49
49
  <HeaderContainer>
50
- <FieldTypeIcon type={getAttrType(type)} />
50
+ <FieldTypeIcon type={getAttrType()} customFieldUid={customFieldUid} />
51
51
  <Typography fontWeight="bold" textColor="neutral800" as="h2" id="title">
52
52
  {formatMessage(
53
53
  {
@@ -81,7 +81,12 @@ const FormModal = ({ onToggle, onMetaChange, onSizeChange, onSubmit, type }) =>
81
81
  );
82
82
  };
83
83
 
84
+ FormModal.defaultProps = {
85
+ customFieldUid: null,
86
+ };
87
+
84
88
  FormModal.propTypes = {
89
+ customFieldUid: PropTypes.string,
85
90
  onSubmit: PropTypes.func.isRequired,
86
91
  onToggle: PropTypes.func.isRequired,
87
92
  onMetaChange: PropTypes.func.isRequired,
@@ -344,9 +344,10 @@ const EditSettingsView = ({ mainLayout, components, isContentTypeView, slug, upd
344
344
  <ModalForm
345
345
  onSubmit={handleMetaSubmit}
346
346
  onToggle={handleToggleModal}
347
- type={get(attributes, [metaToEdit, 'type'], '')}
348
347
  onMetaChange={handleMetaChange}
349
348
  onSizeChange={handleSizeChange}
349
+ type={get(attributes, [metaToEdit, 'type'], '')}
350
+ customFieldUid={get(attributes, [metaToEdit, 'customField'], '')}
350
351
  />
351
352
  )}
352
353
  </Main>
@@ -17,9 +17,15 @@ import { Typography } from '@strapi/design-system/Typography';
17
17
  import { Stack } from '@strapi/design-system/Stack';
18
18
  import ExclamationMarkCircle from '@strapi/icons/ExclamationMarkCircle';
19
19
  import Check from '@strapi/icons/Check';
20
+ import styled from 'styled-components';
20
21
  import { getTrad } from '../../../utils';
21
22
  import { connect, select } from './utils';
22
23
 
24
+ // TODO: replace with textAlign Typography props when available
25
+ const FlexTextAlign = styled(Flex)`
26
+ text-align: center;
27
+ `;
28
+
23
29
  const Header = ({
24
30
  allowedActions: { canUpdate, canCreate, canPublish },
25
31
  initialData,
@@ -31,6 +37,8 @@ const Header = ({
31
37
  onPublish,
32
38
  onUnpublish,
33
39
  status,
40
+ publishConfirmation: { show: showPublishConfirmation, draftCount },
41
+ onPublishPromptDismissal,
34
42
  }) => {
35
43
  const { goBack } = useHistory();
36
44
  const [showWarningUnpublish, setWarningUnpublish] = useState(false);
@@ -150,60 +158,115 @@ const Header = ({
150
158
  </Link>
151
159
  }
152
160
  />
153
- {showWarningUnpublish && (
154
- <Dialog
155
- onClose={toggleWarningUnpublish}
156
- title="Confirmation"
157
- labelledBy="confirmation"
158
- describedBy="confirm-description"
159
- isOpen={showWarningUnpublish}
160
- >
161
- <DialogBody icon={<ExclamationMarkCircle />}>
162
- <Stack spacing={2}>
163
- <Flex justifyContent="center" style={{ textAlign: 'center' }}>
164
- <Typography id="confirm-description">
165
- {formatMessage(
166
- {
167
- id: getTrad('popUpWarning.warning.unpublish'),
168
- defaultMessage:
169
- 'Unpublish this content will automatically change it to a draft.',
170
- },
171
- {
172
- br: () => <br />,
173
- }
174
- )}
175
- </Typography>
176
- </Flex>
177
- <Flex justifyContent="center" style={{ textAlign: 'center' }}>
178
- <Typography id="confirm-description">
179
- {formatMessage({
180
- id: getTrad('popUpWarning.warning.unpublish-question'),
181
- defaultMessage: 'Are you sure you want to unpublish it?',
182
- })}
183
- </Typography>
184
- </Flex>
185
- </Stack>
186
- </DialogBody>
187
- <DialogFooter
188
- startAction={
189
- <Button onClick={toggleWarningUnpublish} variant="tertiary">
161
+ <Dialog
162
+ onClose={toggleWarningUnpublish}
163
+ title="Confirmation"
164
+ labelledBy="confirmation"
165
+ describedBy="confirm-description"
166
+ isOpen={showWarningUnpublish}
167
+ >
168
+ <DialogBody icon={<ExclamationMarkCircle />}>
169
+ <Stack spacing={2}>
170
+ <Flex justifyContent="center" style={{ textAlign: 'center' }}>
171
+ <Typography id="confirm-description">
172
+ {formatMessage(
173
+ {
174
+ id: getTrad('popUpWarning.warning.unpublish'),
175
+ defaultMessage:
176
+ 'Unpublish this content will automatically change it to a draft.',
177
+ },
178
+ {
179
+ br: () => <br />,
180
+ }
181
+ )}
182
+ </Typography>
183
+ </Flex>
184
+ <Flex justifyContent="center" style={{ textAlign: 'center' }}>
185
+ <Typography id="confirm-description">
190
186
  {formatMessage({
191
- id: 'components.popUpWarning.button.cancel',
192
- defaultMessage: 'No, cancel',
187
+ id: getTrad('popUpWarning.warning.unpublish-question'),
188
+ defaultMessage: 'Are you sure you want to unpublish it?',
193
189
  })}
194
- </Button>
195
- }
196
- endAction={
197
- <Button variant="danger-light" onClick={handleUnpublish}>
190
+ </Typography>
191
+ </Flex>
192
+ </Stack>
193
+ </DialogBody>
194
+ <DialogFooter
195
+ startAction={
196
+ <Button onClick={toggleWarningUnpublish} variant="tertiary">
197
+ {formatMessage({
198
+ id: 'components.popUpWarning.button.cancel',
199
+ defaultMessage: 'Cancel',
200
+ })}
201
+ </Button>
202
+ }
203
+ endAction={
204
+ <Button variant="danger-light" onClick={handleUnpublish}>
205
+ {formatMessage({
206
+ id: 'components.popUpWarning.button.confirm',
207
+ defaultMessage: 'Confirm',
208
+ })}
209
+ </Button>
210
+ }
211
+ />
212
+ </Dialog>
213
+ <Dialog
214
+ onClose={onPublishPromptDismissal}
215
+ title={formatMessage({
216
+ id: getTrad(`popUpWarning.warning.has-draft-relations.title`),
217
+ defaultMessage: 'Confirmation',
218
+ })}
219
+ labelledBy="confirmation"
220
+ describedBy="confirm-description"
221
+ isOpen={showPublishConfirmation}
222
+ >
223
+ <DialogBody icon={<ExclamationMarkCircle />}>
224
+ <Stack spacing={2}>
225
+ <FlexTextAlign justifyContent="center">
226
+ <Typography id="confirm-description">
227
+ {draftCount}
228
+ {formatMessage(
229
+ {
230
+ id: getTrad(`popUpwarning.warning.has-draft-relations.message`),
231
+ defaultMessage:
232
+ '<b>{count, plural, one { relation is} other { relations are}}</b> not published yet and might lead to unexpected behavior.',
233
+ },
234
+ {
235
+ b: (chunks) => <Typography fontWeight="bold">{chunks}</Typography>,
236
+ count: draftCount,
237
+ }
238
+ )}
239
+ </Typography>
240
+ </FlexTextAlign>
241
+ <FlexTextAlign justifyContent="center">
242
+ <Typography id="confirm-description">
198
243
  {formatMessage({
199
- id: 'components.popUpWarning.button.confirm',
200
- defaultMessage: 'Yes, confirm',
244
+ id: getTrad('popUpWarning.warning.publish-question'),
245
+ defaultMessage: 'Do you still want to publish?',
201
246
  })}
202
- </Button>
203
- }
204
- />
205
- </Dialog>
206
- )}
247
+ </Typography>
248
+ </FlexTextAlign>
249
+ </Stack>
250
+ </DialogBody>
251
+ <DialogFooter
252
+ startAction={
253
+ <Button onClick={onPublishPromptDismissal} variant="tertiary">
254
+ {formatMessage({
255
+ id: 'components.popUpWarning.button.cancel',
256
+ defaultMessage: 'Cancel',
257
+ })}
258
+ </Button>
259
+ }
260
+ endAction={
261
+ <Button variant="success" onClick={onPublish}>
262
+ {formatMessage({
263
+ id: getTrad('popUpwarning.warning.has-draft-relations.button-confirm'),
264
+ defaultMessage: 'Publish',
265
+ })}
266
+ </Button>
267
+ }
268
+ />
269
+ </Dialog>
207
270
  </>
208
271
  );
209
272
  };
@@ -223,6 +286,11 @@ Header.propTypes = {
223
286
  modifiedData: PropTypes.object.isRequired,
224
287
  onPublish: PropTypes.func.isRequired,
225
288
  onUnpublish: PropTypes.func.isRequired,
289
+ publishConfirmation: PropTypes.shape({
290
+ show: PropTypes.bool.isRequired,
291
+ draftCount: PropTypes.number.isRequired,
292
+ }).isRequired,
293
+ onPublishPromptDismissal: PropTypes.func.isRequired,
226
294
  };
227
295
 
228
296
  const Memoized = memo(Header, isEqualFastCompare);
@@ -11,6 +11,8 @@ function useSelect() {
11
11
  modifiedData,
12
12
  onPublish,
13
13
  onUnpublish,
14
+ publishConfirmation,
15
+ onPublishPromptDismissal,
14
16
  } = useCMEditViewDataManager();
15
17
 
16
18
  return {
@@ -23,6 +25,8 @@ function useSelect() {
23
25
  modifiedData,
24
26
  onPublish,
25
27
  onUnpublish,
28
+ publishConfirmation,
29
+ onPublishPromptDismissal,
26
30
  };
27
31
  }
28
32
 
@@ -1,7 +1,12 @@
1
- import React, { memo, useCallback, useMemo } from 'react';
1
+ import React, { Suspense, memo, useCallback, useMemo } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import get from 'lodash/get';
4
- import { CheckPermissions, useTracking, LinkButton } from '@strapi/helper-plugin';
4
+ import {
5
+ CheckPermissions,
6
+ LoadingIndicatorPage,
7
+ useTracking,
8
+ LinkButton,
9
+ } from '@strapi/helper-plugin';
5
10
  import { useIntl } from 'react-intl';
6
11
  import { ContentLayout } from '@strapi/design-system/Layout';
7
12
  import { Box } from '@strapi/design-system/Box';
@@ -93,6 +98,7 @@ const EditView = ({
93
98
  onDeleteSucceeded,
94
99
  onPost,
95
100
  onPublish,
101
+ onDraftRelationCheck,
96
102
  onPut,
97
103
  onUnpublish,
98
104
  redirectionLink,
@@ -112,6 +118,7 @@ const EditView = ({
112
118
  isSingleType={isSingleType}
113
119
  onPost={onPost}
114
120
  onPublish={onPublish}
121
+ onDraftRelationCheck={onDraftRelationCheck}
115
122
  onPut={onPut}
116
123
  onUnpublish={onUnpublish}
117
124
  readActionAllowedFields={readActionAllowedFields}
@@ -125,108 +132,110 @@ const EditView = ({
125
132
  <ContentLayout>
126
133
  <Grid gap={4}>
127
134
  <GridItem col={9} s={12}>
128
- <Stack spacing={6}>
129
- {formattedContentTypeLayout.map((row, index) => {
130
- if (isDynamicZone(row)) {
131
- const {
132
- 0: {
133
- 0: { name, fieldSchema, metadatas, labelAction },
134
- },
135
- } = row;
135
+ <Suspense fallback={<LoadingIndicatorPage />}>
136
+ <Stack spacing={6}>
137
+ {formattedContentTypeLayout.map((row, index) => {
138
+ if (isDynamicZone(row)) {
139
+ const {
140
+ 0: {
141
+ 0: { name, fieldSchema, metadatas, labelAction },
142
+ },
143
+ } = row;
144
+
145
+ return (
146
+ <Box key={index}>
147
+ <Grid gap={4}>
148
+ <GridItem col={12} s={12} xs={12}>
149
+ <DynamicZone
150
+ name={name}
151
+ fieldSchema={fieldSchema}
152
+ labelAction={labelAction}
153
+ metadatas={metadatas}
154
+ />
155
+ </GridItem>
156
+ </Grid>
157
+ </Box>
158
+ );
159
+ }
136
160
 
137
161
  return (
138
- <Box key={index}>
139
- <Grid gap={4}>
140
- <GridItem col={12} s={12} xs={12}>
141
- <DynamicZone
142
- name={name}
143
- fieldSchema={fieldSchema}
144
- labelAction={labelAction}
145
- metadatas={metadatas}
146
- />
147
- </GridItem>
148
- </Grid>
149
- </Box>
150
- );
151
- }
162
+ <Box
163
+ key={index}
164
+ hasRadius
165
+ background="neutral0"
166
+ shadow="tableShadow"
167
+ paddingLeft={6}
168
+ paddingRight={6}
169
+ paddingTop={6}
170
+ paddingBottom={6}
171
+ borderColor="neutral150"
172
+ >
173
+ <Stack spacing={6}>
174
+ {row.map((grid, gridIndex) => {
175
+ return (
176
+ <Grid gap={4} key={gridIndex}>
177
+ {grid.map(
178
+ ({
179
+ fieldSchema,
180
+ labelAction,
181
+ metadatas,
182
+ name,
183
+ size,
184
+ queryInfos,
185
+ }) => {
186
+ const isComponent = fieldSchema.type === 'component';
152
187
 
153
- return (
154
- <Box
155
- key={index}
156
- hasRadius
157
- background="neutral0"
158
- shadow="tableShadow"
159
- paddingLeft={6}
160
- paddingRight={6}
161
- paddingTop={6}
162
- paddingBottom={6}
163
- borderColor="neutral150"
164
- >
165
- <Stack spacing={6}>
166
- {row.map((grid, gridIndex) => {
167
- return (
168
- <Grid gap={4} key={gridIndex}>
169
- {grid.map(
170
- ({
171
- fieldSchema,
172
- labelAction,
173
- metadatas,
174
- name,
175
- size,
176
- queryInfos,
177
- }) => {
178
- const isComponent = fieldSchema.type === 'component';
188
+ if (isComponent) {
189
+ const {
190
+ component,
191
+ max,
192
+ min,
193
+ repeatable = false,
194
+ required = false,
195
+ } = fieldSchema;
179
196
 
180
- if (isComponent) {
181
- const {
182
- component,
183
- max,
184
- min,
185
- repeatable = false,
186
- required = false,
187
- } = fieldSchema;
197
+ return (
198
+ <GridItem col={size} s={12} xs={12} key={component}>
199
+ <FieldComponent
200
+ componentUid={component}
201
+ labelAction={labelAction}
202
+ isRepeatable={repeatable}
203
+ intlLabel={{
204
+ id: metadatas.label,
205
+ defaultMessage: metadatas.label,
206
+ }}
207
+ max={max}
208
+ min={min}
209
+ name={name}
210
+ required={required}
211
+ />
212
+ </GridItem>
213
+ );
214
+ }
188
215
 
189
216
  return (
190
- <GridItem col={size} s={12} xs={12} key={component}>
191
- <FieldComponent
192
- componentUid={component}
217
+ <GridItem col={size} key={name} s={12} xs={12}>
218
+ <Inputs
219
+ size={size}
220
+ fieldSchema={fieldSchema}
221
+ keys={name}
193
222
  labelAction={labelAction}
194
- isRepeatable={repeatable}
195
- intlLabel={{
196
- id: metadatas.label,
197
- defaultMessage: metadatas.label,
198
- }}
199
- max={max}
200
- min={min}
201
- name={name}
202
- required={required}
223
+ metadatas={metadatas}
224
+ queryInfos={queryInfos}
203
225
  />
204
226
  </GridItem>
205
227
  );
206
228
  }
207
-
208
- return (
209
- <GridItem col={size} key={name} s={12} xs={12}>
210
- <Inputs
211
- size={size}
212
- fieldSchema={fieldSchema}
213
- keys={name}
214
- labelAction={labelAction}
215
- metadatas={metadatas}
216
- queryInfos={queryInfos}
217
- />
218
- </GridItem>
219
- );
220
- }
221
- )}
222
- </Grid>
223
- );
224
- })}
225
- </Stack>
226
- </Box>
227
- );
228
- })}
229
- </Stack>
229
+ )}
230
+ </Grid>
231
+ );
232
+ })}
233
+ </Stack>
234
+ </Box>
235
+ );
236
+ })}
237
+ </Stack>
238
+ </Suspense>
230
239
  </GridItem>
231
240
  <GridItem col={3} s={12}>
232
241
  <Stack spacing={2}>
@@ -5,9 +5,11 @@ import { connect } from 'react-redux';
5
5
  import isEqual from 'react-fast-compare';
6
6
  import { bindActionCreators, compose } from 'redux';
7
7
  import { useIntl } from 'react-intl';
8
- import { useHistory, useLocation } from 'react-router-dom';
8
+ import { useHistory, useLocation, Link as ReactRouterLink } from 'react-router-dom';
9
9
  import get from 'lodash/get';
10
10
  import { stringify } from 'qs';
11
+ import axios from 'axios';
12
+
11
13
  import {
12
14
  NoPermissions,
13
15
  CheckPermissions,
@@ -19,31 +21,37 @@ import {
19
21
  useTracking,
20
22
  Link,
21
23
  } from '@strapi/helper-plugin';
24
+
22
25
  import { IconButton } from '@strapi/design-system/IconButton';
23
26
  import { Main } from '@strapi/design-system/Main';
24
27
  import { Box } from '@strapi/design-system/Box';
25
28
  import { ActionLayout, ContentLayout, HeaderLayout } from '@strapi/design-system/Layout';
26
29
  import { useNotifyAT } from '@strapi/design-system/LiveRegions';
27
30
  import { Button } from '@strapi/design-system/Button';
31
+
28
32
  import ArrowLeft from '@strapi/icons/ArrowLeft';
29
33
  import Plus from '@strapi/icons/Plus';
30
34
  import Cog from '@strapi/icons/Cog';
31
- import axios from 'axios';
35
+
32
36
  import { axiosInstance } from '../../../core/utils';
33
- import { InjectionZone } from '../../../shared/components';
37
+
34
38
  import DynamicTable from '../../components/DynamicTable';
39
+ import AttributeFilter from '../../components/AttributeFilter';
40
+ import { InjectionZone } from '../../../shared/components';
41
+
35
42
  import permissions from '../../../permissions';
43
+
36
44
  import { getRequestUrl, getTrad } from '../../utils';
45
+
37
46
  import FieldPicker from './FieldPicker';
38
47
  import PaginationFooter from './PaginationFooter';
39
48
  import { getData, getDataSucceeded, onChangeListHeaders, onResetListHeaders } from './actions';
40
49
  import makeSelectListView from './selectors';
41
50
  import { buildQueryString } from './utils';
42
- import AttributeFilter from '../../components/AttributeFilter';
43
51
 
44
52
  const cmPermissions = permissions.contentManager;
45
53
 
46
- const IconButtonCustom = styled(IconButton)`
54
+ const ConfigureLayoutBox = styled(Box)`
47
55
  svg {
48
56
  path {
49
57
  fill: ${({ theme }) => theme.colors.neutral900};
@@ -51,7 +59,6 @@ const IconButtonCustom = styled(IconButton)`
51
59
  }
52
60
  `;
53
61
 
54
- /* eslint-disable react/no-array-index-key */
55
62
  function ListView({
56
63
  canCreate,
57
64
  canDelete,
@@ -240,16 +247,18 @@ function ListView({
240
247
  canCreate ? (
241
248
  <Button
242
249
  {...props}
250
+ forwardedAs={ReactRouterLink}
243
251
  onClick={() => {
244
252
  const trackerProperty = hasDraftAndPublish ? { status: 'draft' } : {};
245
253
 
246
254
  trackUsageRef.current('willCreateEntry', trackerProperty);
247
- push({
248
- pathname: `${pathname}/create`,
249
- search: query.plugins ? pluginsQueryParams : '',
250
- });
255
+ }}
256
+ to={{
257
+ pathname: `${pathname}/create`,
258
+ search: query.plugins ? pluginsQueryParams : '',
251
259
  }}
252
260
  startIcon={<Plus />}
261
+ style={{ textDecoration: 'none' }}
253
262
  >
254
263
  {formatMessage({
255
264
  id: getTrad('HeaderLayout.button.label-add-entry'),
@@ -283,20 +292,20 @@ function ListView({
283
292
  <InjectionZone area="contentManager.listView.actions" />
284
293
  <FieldPicker layout={layout} />
285
294
  <CheckPermissions permissions={cmPermissions.collectionTypesConfigurations}>
286
- <Box paddingTop={1} paddingBottom={1}>
287
- <IconButtonCustom
295
+ <ConfigureLayoutBox paddingTop={1} paddingBottom={1}>
296
+ <IconButton
288
297
  onClick={() => {
289
298
  trackUsage('willEditListLayout');
290
-
291
- push({ pathname: `${slug}/configurations/list`, search: pluginsQueryParams });
292
299
  }}
300
+ forwardedAs={ReactRouterLink}
301
+ to={{ pathname: `${slug}/configurations/list`, search: pluginsQueryParams }}
293
302
  icon={<Cog />}
294
303
  label={formatMessage({
295
304
  id: 'app.links.configure-view',
296
305
  defaultMessage: 'Configure the view',
297
306
  })}
298
307
  />
299
- </Box>
308
+ </ConfigureLayoutBox>
300
309
  </CheckPermissions>
301
310
  </>
302
311
  }
@@ -1,4 +1,5 @@
1
1
  import { stringify } from 'qs';
2
+ import set from 'lodash/set';
2
3
  import createPluginsFilter from './createPluginsFilter';
3
4
 
4
5
  /**
@@ -12,12 +13,23 @@ const buildQueryString = (queryParams = {}) => {
12
13
  * Extracting pluginOptions from the query since we don't want them to be part
13
14
  * of the url
14
15
  */
15
- const { plugins: _, ...otherQueryParams } = {
16
+ const {
17
+ plugins: _,
18
+ _q: query,
19
+ ...otherQueryParams
20
+ } = {
16
21
  ...queryParams,
17
22
  ...createPluginsFilter(queryParams.plugins),
18
23
  };
19
24
 
20
- return `?${stringify(otherQueryParams, { encode: false })}`;
25
+ if (query) {
26
+ set(otherQueryParams, `_q`, encodeURIComponent(query));
27
+ }
28
+
29
+ return `${stringify(otherQueryParams, {
30
+ encode: false,
31
+ addQueryPrefix: true,
32
+ })}`;
21
33
  };
22
34
 
23
35
  export default buildQueryString;
@@ -0,0 +1,24 @@
1
+ import React, { createContext, useContext } from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ const ApiTokenPermissionsContext = createContext({});
5
+
6
+ const ApiTokenPermissionsContextProvider = ({ children, ...rest }) => {
7
+ return (
8
+ <ApiTokenPermissionsContext.Provider value={rest}>
9
+ {children}
10
+ </ApiTokenPermissionsContext.Provider>
11
+ );
12
+ };
13
+
14
+ const useApiTokenPermissionsContext = () => useContext(ApiTokenPermissionsContext);
15
+
16
+ ApiTokenPermissionsContextProvider.propTypes = {
17
+ children: PropTypes.node.isRequired,
18
+ };
19
+
20
+ export {
21
+ ApiTokenPermissionsContext,
22
+ ApiTokenPermissionsContextProvider,
23
+ useApiTokenPermissionsContext,
24
+ };