@strapi/admin 4.6.0-beta.2 → 4.6.1

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 (228) hide show
  1. package/.browserslistrc +2 -1
  2. package/admin/src/components/AuthenticatedApp/utils/api.js +5 -4
  3. package/admin/src/components/ConfigurationsProvider/index.js +21 -18
  4. package/admin/src/components/ConfigurationsProvider/reducer.js +1 -0
  5. package/admin/src/components/LeftMenu/index.js +62 -53
  6. package/admin/src/components/UnauthenticatedLogo/index.js +1 -1
  7. package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +20 -16
  8. package/admin/src/content-manager/components/DynamicTable/CellContent/RelationMultiple/index.js +5 -5
  9. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findLeafByPathAndReplace.js +1 -3
  10. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/schema.js +6 -5
  11. package/admin/src/content-manager/components/Hint/index.js +4 -17
  12. package/admin/src/content-manager/components/InputUID/index.js +7 -18
  13. package/admin/src/content-manager/components/Inputs/index.js +0 -2
  14. package/admin/src/content-manager/components/PreviewWysiwyg/Wrapper.js +22 -27
  15. package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +35 -14
  16. package/admin/src/content-manager/components/Wysiwyg/EditorLayout.js +19 -28
  17. package/admin/src/content-manager/components/Wysiwyg/index.js +4 -8
  18. package/admin/src/content-manager/hooks/useFetchContentTypeLayout/index.js +4 -3
  19. package/admin/src/content-manager/hooks/useLazyComponents/index.js +9 -13
  20. package/admin/src/content-manager/hooks/useRelation/useRelation.js +4 -4
  21. package/admin/src/content-manager/pages/App/LeftMenu/index.js +3 -8
  22. package/admin/src/content-manager/pages/App/LeftMenu/utils/index.js +1 -0
  23. package/admin/src/content-manager/pages/App/LeftMenu/utils/matchByTitle.js +24 -0
  24. package/admin/src/content-manager/pages/App/useModels.js +8 -3
  25. package/admin/src/content-manager/pages/App/utils/getContentTypeLinks.js +3 -2
  26. package/admin/src/content-manager/pages/ComponentSetttingsView/index.js +4 -4
  27. package/admin/src/content-manager/pages/EditSettingsView/utils/api.js +4 -2
  28. package/admin/src/content-manager/pages/EditView/{Informations → Information}/index.js +55 -39
  29. package/admin/src/content-manager/pages/EditView/{Informations → Information}/utils/getUnits.js +0 -0
  30. package/admin/src/content-manager/pages/EditView/index.js +3 -3
  31. package/admin/src/content-manager/pages/ListSettingsView/utils/api.js +4 -2
  32. package/admin/src/content-manager/pages/ListView/index.js +9 -9
  33. package/admin/src/core/store/configureStore.js +22 -4
  34. package/admin/src/core/utils/index.js +0 -1
  35. package/admin/src/hooks/useFetchEnabledPlugins/utils/api.js +3 -2
  36. package/admin/src/hooks/useInjectReducer/index.js +1 -0
  37. package/admin/src/hooks/useInjectReducer/useInjectReducer.js +19 -0
  38. package/admin/src/hooks/useRegenerate/index.js +3 -3
  39. package/admin/src/hooks/useRolesList/index.js +5 -3
  40. package/admin/src/hooks/useSettingsMenu/init.js +2 -25
  41. package/admin/src/hooks/useSettingsMenu/utils/adminLinks.js +4 -0
  42. package/admin/src/hooks/useSettingsMenu/utils/customAdminLinks.js +1 -0
  43. package/admin/src/hooks/useSettingsMenu/utils/defaultAdminLinks.js +21 -0
  44. package/admin/src/index.js +5 -4
  45. package/admin/src/pages/App/index.js +6 -2
  46. package/admin/src/pages/ProfilePage/utils/api.js +5 -3
  47. package/admin/src/pages/SettingsPage/{pages/Users/ListPage → components}/Filters/index.js +0 -0
  48. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +6 -5
  49. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +4 -3
  50. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/CustomizationInfos/index.js +142 -0
  51. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/{Form → CustomizationInfos}/init.js +3 -0
  52. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/{Form → CustomizationInfos}/reducer.js +20 -0
  53. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/index.js +21 -17
  54. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/index.js +68 -42
  55. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/api.js +9 -3
  56. package/admin/src/pages/SettingsPage/pages/Users/EditPage/utils/api.js +6 -3
  57. package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/index.js +9 -3
  58. package/admin/src/pages/SettingsPage/pages/Users/ListPage/index.js +1 -1
  59. package/admin/src/pages/SettingsPage/pages/Users/ListPage/utils/api.js +6 -3
  60. package/admin/src/pages/SettingsPage/pages/Users/components/SelectRoles/index.js +3 -2
  61. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/EventInput/index.js +1 -1
  62. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/index.js +3 -2
  63. package/admin/src/pages/SettingsPage/utils/defaultRoutes.js +0 -11
  64. package/admin/src/permissions/defaultPermissions.js +4 -0
  65. package/admin/src/translations/en.json +29 -21
  66. package/admin/src/translations/eu.json +796 -0
  67. package/admin/src/translations/languageNativeNames.js +1 -0
  68. package/admin/src/translations/ru.json +9 -9
  69. package/build/1412.936ed920.chunk.js +159 -0
  70. package/build/1683.c8aa7b7c.chunk.js +268 -0
  71. package/build/2607.2e48dbf8.chunk.js +66 -0
  72. package/build/2743.6d1632f9.chunk.js +45 -0
  73. package/build/3075.dc3894fe.chunk.js +108 -0
  74. package/build/3632.0317b618.chunk.js +138 -0
  75. package/build/4318.f96a9d4d.chunk.js +30 -0
  76. package/build/{3557.e7115160.chunk.js → 4855.bd092921.chunk.js} +131 -91
  77. package/build/{5015.f5e15fdb.chunk.js → 5015.8e3fe50b.chunk.js} +1 -1
  78. package/build/8633.00ccd382.chunk.js +1 -0
  79. package/build/9707.7290fd92.chunk.js +96 -0
  80. package/build/Admin-authenticatedApp.ce646f66.chunk.js +75 -0
  81. package/build/Admin_homePage.b1730882.chunk.js +77 -0
  82. package/build/Admin_marketplace.ea0316c2.chunk.js +26 -0
  83. package/build/Admin_pluginsPage.5c24f963.chunk.js +6 -0
  84. package/build/Admin_profilePage.59af1978.chunk.js +15 -0
  85. package/build/Admin_settingsPage.d1493824.chunk.js +178 -0
  86. package/build/{Upload_ConfigureTheView.9bdf41b5.chunk.js → Upload_ConfigureTheView.3f2b6e6a.chunk.js} +1 -1
  87. package/build/admin-app.25934eaa.chunk.js +112 -0
  88. package/build/admin-edit-roles-page.446b69dc.chunk.js +1 -0
  89. package/build/admin-edit-users.2ed69bfd.chunk.js +10 -0
  90. package/build/admin-users.fc003b10.chunk.js +11 -0
  91. package/build/{api-tokens-create-page.0e686c30.chunk.js → api-tokens-create-page.d248362d.chunk.js} +1 -1
  92. package/build/{api-tokens-edit-page.d6c7487b.chunk.js → api-tokens-edit-page.8516fa20.chunk.js} +1 -1
  93. package/build/api-tokens-list-page.44a79fda.chunk.js +16 -0
  94. package/build/audit-logs-settings-page.c3dce30d.chunk.js +1 -0
  95. package/build/content-manager.35ff9726.chunk.js +1139 -0
  96. package/build/content-type-builder-list-view.79e84b36.chunk.js +193 -0
  97. package/build/{content-type-builder-translation-de-json.29df67b8.chunk.js → content-type-builder-translation-de-json.0979cccb.chunk.js} +1 -1
  98. package/build/{content-type-builder-translation-dk-json.e22d2527.chunk.js → content-type-builder-translation-dk-json.e05583e9.chunk.js} +1 -1
  99. package/build/content-type-builder-translation-en-json.e577d595.chunk.js +1 -0
  100. package/build/{content-type-builder-translation-es-json.1044b252.chunk.js → content-type-builder-translation-es-json.fe4daad8.chunk.js} +1 -1
  101. package/build/{content-type-builder-translation-fr-json.2183e6b3.chunk.js → content-type-builder-translation-fr-json.b1eb52f6.chunk.js} +1 -1
  102. package/build/{content-type-builder-translation-id-json.ba3e8891.chunk.js → content-type-builder-translation-id-json.ee3b36bb.chunk.js} +1 -1
  103. package/build/{content-type-builder-translation-it-json.d4661201.chunk.js → content-type-builder-translation-it-json.13b3c26a.chunk.js} +1 -1
  104. package/build/{content-type-builder-translation-ko-json.57ff7f51.chunk.js → content-type-builder-translation-ko-json.8a274be5.chunk.js} +1 -1
  105. package/build/{content-type-builder-translation-pl-json.a057b51e.chunk.js → content-type-builder-translation-pl-json.24a34349.chunk.js} +1 -1
  106. package/build/{content-type-builder-translation-pt-BR-json.446df9da.chunk.js → content-type-builder-translation-pt-BR-json.97f71a9d.chunk.js} +1 -1
  107. package/build/{content-type-builder-translation-ru-json.8c51843e.chunk.js → content-type-builder-translation-ru-json.54d11230.chunk.js} +1 -1
  108. package/build/{content-type-builder-translation-sv-json.af6ecca1.chunk.js → content-type-builder-translation-sv-json.59f5e1e5.chunk.js} +1 -1
  109. package/build/{content-type-builder-translation-tr-json.da83a07e.chunk.js → content-type-builder-translation-tr-json.cea4d226.chunk.js} +1 -1
  110. package/build/{content-type-builder-translation-zh-json.42f94cb3.chunk.js → content-type-builder-translation-zh-json.faedd610.chunk.js} +1 -1
  111. package/build/content-type-builder.855db321.chunk.js +126 -0
  112. package/build/email-settings-page.d1fcc7a3.chunk.js +10 -0
  113. package/build/en-json.1f137a90.chunk.js +1 -0
  114. package/build/eu-json.fceecd8b.chunk.js +1 -0
  115. package/build/i18n-settings-page.b8d8753e.chunk.js +60 -0
  116. package/build/{i18n-translation-de-json.dc876c08.chunk.js → i18n-translation-de-json.362384a6.chunk.js} +1 -1
  117. package/build/{i18n-translation-dk-json.49aaf933.chunk.js → i18n-translation-dk-json.89401417.chunk.js} +1 -1
  118. package/build/{i18n-translation-en-json.ac9ebc1b.chunk.js → i18n-translation-en-json.60af6722.chunk.js} +1 -1
  119. package/build/{i18n-translation-es-json.57072ed3.chunk.js → i18n-translation-es-json.87b494d1.chunk.js} +1 -1
  120. package/build/{i18n-translation-fr-json.84733f34.chunk.js → i18n-translation-fr-json.57ddc77e.chunk.js} +1 -1
  121. package/build/{i18n-translation-ko-json.fc73fe20.chunk.js → i18n-translation-ko-json.ef4f9471.chunk.js} +1 -1
  122. package/build/{i18n-translation-pl-json.16e5df90.chunk.js → i18n-translation-pl-json.dfac513d.chunk.js} +1 -1
  123. package/build/{i18n-translation-tr-json.cb39c048.chunk.js → i18n-translation-tr-json.10f0600d.chunk.js} +1 -1
  124. package/build/{i18n-translation-zh-Hans-json.2cf82d2d.chunk.js → i18n-translation-zh-Hans-json.757ce62d.chunk.js} +1 -1
  125. package/build/{i18n-translation-zh-json.ed1d272e.chunk.js → i18n-translation-zh-json.bef2dc07.chunk.js} +1 -1
  126. package/build/index.html +1 -1
  127. package/build/main.7b151630.js +4377 -0
  128. package/build/ru-json.aa5cd123.chunk.js +1 -0
  129. package/build/runtime~main.a20d633b.js +2 -0
  130. package/build/sso-settings-page.b85ad080.chunk.js +41 -0
  131. package/build/upload-settings.ef64bbf9.chunk.js +84 -0
  132. package/build/upload.c5730dfa.chunk.js +33 -0
  133. package/build/users-advanced-settings-page.fce9908e.chunk.js +8 -0
  134. package/build/users-email-settings-page.343d0ad2.chunk.js +23 -0
  135. package/build/users-providers-settings-page.e5a9a3f1.chunk.js +99 -0
  136. package/build/users-roles-settings-page.66312f31.chunk.js +30 -0
  137. package/build/webhook-edit-page.73e51e64.chunk.js +75 -0
  138. package/build/webhook-list-page.1134f130.chunk.js +42 -0
  139. package/ee/admin/hooks/useSettingsMenu/utils/customAdminLinks.js +17 -0
  140. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/ComboboxFilter/index.js +41 -0
  141. package/{admin/src → ee/admin}/pages/SettingsPage/pages/AuditLogs/ListView/Modal/ActionBody.js +1 -3
  142. package/{admin/src → ee/admin}/pages/SettingsPage/pages/AuditLogs/ListView/Modal/ActionItem.js +0 -0
  143. package/{admin/src → ee/admin}/pages/SettingsPage/pages/AuditLogs/ListView/Modal/index.js +5 -1
  144. package/{admin/src → ee/admin}/pages/SettingsPage/pages/AuditLogs/ListView/PaginationFooter/index.js +0 -0
  145. package/{admin/src → ee/admin}/pages/SettingsPage/pages/AuditLogs/ListView/TableRows/index.js +1 -1
  146. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/hooks/useAuditLogsData.js +47 -0
  147. package/{admin/src → ee/admin}/pages/SettingsPage/pages/AuditLogs/ListView/hooks/useFormatTimeStamp.js +0 -0
  148. package/{admin/src → ee/admin}/pages/SettingsPage/pages/AuditLogs/ListView/index.js +35 -36
  149. package/{admin/src → ee/admin}/pages/SettingsPage/pages/AuditLogs/ListView/utils/getActionTypesDefaultMessages.js +10 -9
  150. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/utils/getDisplayedFilters.js +88 -0
  151. package/{admin/src → ee/admin}/pages/SettingsPage/pages/AuditLogs/ListView/utils/tableHeaders.js +0 -0
  152. package/{admin/src → ee/admin}/pages/SettingsPage/pages/AuditLogs/ProtectedListPage/index.js +1 -1
  153. package/ee/admin/pages/SettingsPage/pages/Roles/ListPage/index.js +4 -2
  154. package/ee/admin/pages/SettingsPage/{SingleSignOn → pages/SingleSignOn}/index.js +3 -3
  155. package/ee/admin/pages/SettingsPage/{SingleSignOn → pages/SingleSignOn}/utils/schema.js +0 -0
  156. package/ee/admin/pages/SettingsPage/utils/customRoutes.js +28 -16
  157. package/ee/server/bootstrap.js +2 -0
  158. package/ee/server/migrations/audit-logs-table.js +45 -0
  159. package/ee/server/register.js +2 -0
  160. package/ee/server/routes/index.js +94 -10
  161. package/ee/server/services/audit-logs.js +30 -2
  162. package/ee/server/services/passport/sso.js +13 -1
  163. package/ee/server/services/passport.js +1 -4
  164. package/package.json +27 -32
  165. package/server/controllers/admin.js +19 -2
  166. package/server/register.js +7 -7
  167. package/server/services/project-settings.js +10 -6
  168. package/server/services/user.js +3 -1
  169. package/server/validation/project-settings.js +19 -10
  170. package/strapi-server.js +1 -1
  171. package/admin/src/content-manager/components/InputJSON/FieldWrapper.js +0 -40
  172. package/admin/src/content-manager/components/InputJSON/Label.js +0 -35
  173. package/admin/src/content-manager/components/InputJSON/components.js +0 -36
  174. package/admin/src/content-manager/components/InputJSON/index.js +0 -223
  175. package/admin/src/content-manager/components/InputJSON/jsonlint.js +0 -680
  176. package/admin/src/core/store/createReducer.js +0 -5
  177. package/admin/src/core/utils/axiosInstance.js +0 -38
  178. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/index.js +0 -85
  179. package/build/2235.746d3cf7.chunk.js +0 -106
  180. package/build/2598.01c96bd5.chunk.js +0 -159
  181. package/build/2743.692b1f21.chunk.js +0 -42
  182. package/build/4318.87affaf2.chunk.js +0 -30
  183. package/build/4958.1979bbf5.chunk.js +0 -276
  184. package/build/5052.c2eacff2.chunk.js +0 -65
  185. package/build/7295.4e2dfbbb.chunk.js +0 -114
  186. package/build/805.da20168c.chunk.js +0 -138
  187. package/build/8633.6f546066.chunk.js +0 -1
  188. package/build/874.be41e4b3.chunk.js +0 -104
  189. package/build/9707.a07db355.chunk.js +0 -101
  190. package/build/Admin-authenticatedApp.9933974c.chunk.js +0 -75
  191. package/build/Admin_homePage.045bb0c8.chunk.js +0 -77
  192. package/build/Admin_marketplace.bf3ac090.chunk.js +0 -26
  193. package/build/Admin_pluginsPage.d2a9a619.chunk.js +0 -6
  194. package/build/Admin_profilePage.5e830ceb.chunk.js +0 -15
  195. package/build/Admin_settingsPage.53fa00a4.chunk.js +0 -178
  196. package/build/admin-app.8ed108ca.chunk.js +0 -112
  197. package/build/admin-audit-logs.68f833bf.chunk.js +0 -1
  198. package/build/admin-edit-roles-page.32bfe5ea.chunk.js +0 -1
  199. package/build/admin-edit-users.795f155c.chunk.js +0 -10
  200. package/build/admin-users.cbd9bcf7.chunk.js +0 -11
  201. package/build/api-tokens-list-page.a55e427c.chunk.js +0 -16
  202. package/build/codemirror-addon-closebrackets.71aa4bbd.chunk.js +0 -2
  203. package/build/codemirror-addon-lint-js.405f70fb.chunk.js +0 -1
  204. package/build/codemirror-addon-lint.8487ad3d.chunk.js +0 -1
  205. package/build/codemirror-addon-mark-selection.1928c849.chunk.js +0 -1
  206. package/build/codemirror-css.359a2a4b.chunk.js +0 -345
  207. package/build/codemirror-javacript.af237b68.chunk.js +0 -1
  208. package/build/codemirror-theme.2fe63a16.chunk.js +0 -33
  209. package/build/content-manager.ad929a94.chunk.js +0 -1174
  210. package/build/content-type-builder-list-view.3048854d.chunk.js +0 -198
  211. package/build/content-type-builder-translation-en-json.08e28f4e.chunk.js +0 -1
  212. package/build/content-type-builder.4edd1c22.chunk.js +0 -127
  213. package/build/email-settings-page.7c9e6c5e.chunk.js +0 -15
  214. package/build/en-json.d65a13ef.chunk.js +0 -1
  215. package/build/i18n-settings-page.fbccdf12.chunk.js +0 -1
  216. package/build/main.6bbf9950.js +0 -4417
  217. package/build/ru-json.3b411a39.chunk.js +0 -1
  218. package/build/runtime~main.c2bf62af.js +0 -2
  219. package/build/sso-settings-page.4031de9e.chunk.js +0 -41
  220. package/build/upload-settings.657790fd.chunk.js +0 -89
  221. package/build/upload.608a9856.chunk.js +0 -38
  222. package/build/users-advanced-settings-page.e3ab865f.chunk.js +0 -13
  223. package/build/users-email-settings-page.57adf9b7.chunk.js +0 -28
  224. package/build/users-providers-settings-page.7d1fb45c.chunk.js +0 -1
  225. package/build/users-roles-settings-page.ad28ab42.chunk.js +0 -30
  226. package/build/webhook-edit-page.1dd6d040.chunk.js +0 -75
  227. package/build/webhook-list-page.98afa3ea.chunk.js +0 -42
  228. package/ee/server/routes/features-routes.js +0 -66
@@ -0,0 +1,142 @@
1
+ import React, { useReducer, forwardRef, useImperativeHandle } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { useIntl } from 'react-intl';
4
+ import { useTracking } from '@strapi/helper-plugin';
5
+ import { Grid, GridItem } from '@strapi/design-system/Grid';
6
+ import { Box } from '@strapi/design-system/Box';
7
+ import { Typography } from '@strapi/design-system/Typography';
8
+ import { useConfigurations } from '../../../../../../hooks';
9
+ import { DIMENSION, SIZE } from '../../utils/constants';
10
+ import LogoInput from '../LogoInput';
11
+ import reducer, { initialState } from './reducer';
12
+ import init from './init';
13
+
14
+ const CustomizationInfos = forwardRef(({ canUpdate, projectSettingsStored }, ref) => {
15
+ const { formatMessage } = useIntl();
16
+ const { trackUsage } = useTracking();
17
+ const {
18
+ logos: { menu, auth },
19
+ } = useConfigurations();
20
+ const [{ menuLogo, authLogo }, dispatch] = useReducer(reducer, initialState, () =>
21
+ init(initialState, projectSettingsStored)
22
+ );
23
+
24
+ const handleChangeMenuLogo = (asset) => {
25
+ dispatch({
26
+ type: 'SET_CUSTOM_MENU_LOGO',
27
+ value: asset,
28
+ });
29
+ };
30
+
31
+ const handleResetMenuLogo = () => {
32
+ trackUsage('didClickResetLogo', {
33
+ logo: 'menu',
34
+ });
35
+
36
+ dispatch({
37
+ type: 'RESET_CUSTOM_MENU_LOGO',
38
+ });
39
+ };
40
+
41
+ const handleChangeAuthLogo = (asset) => {
42
+ dispatch({
43
+ type: 'SET_CUSTOM_AUTH_LOGO',
44
+ value: asset,
45
+ });
46
+ };
47
+
48
+ const handleResetAuthLogo = () => {
49
+ trackUsage('didClickResetLogo', {
50
+ logo: 'auth',
51
+ });
52
+
53
+ dispatch({
54
+ type: 'RESET_CUSTOM_AUTH_LOGO',
55
+ });
56
+ };
57
+
58
+ useImperativeHandle(ref, () => ({
59
+ getValues: () => ({ menuLogo: menuLogo.submit, authLogo: authLogo.submit }),
60
+ }));
61
+
62
+ return (
63
+ <Box
64
+ hasRadius
65
+ background="neutral0"
66
+ shadow="tableShadow"
67
+ paddingTop={6}
68
+ paddingBottom={6}
69
+ paddingRight={7}
70
+ paddingLeft={7}
71
+ >
72
+ <Typography variant="delta" as="h3">
73
+ {formatMessage({
74
+ id: 'Settings.application.customization',
75
+ defaultMessage: 'Customization',
76
+ })}
77
+ </Typography>
78
+ <Typography variant="pi" textColor="neutral600">
79
+ {formatMessage(
80
+ {
81
+ id: 'Settings.application.customization.size-details',
82
+ defaultMessage: 'Max dimension: {dimension}×{dimension}, Max file size: {size}KB',
83
+ },
84
+ { dimension: DIMENSION, size: SIZE }
85
+ )}
86
+ </Typography>
87
+ <Grid paddingTop={4} gap={4}>
88
+ <GridItem col={6} s={12}>
89
+ <LogoInput
90
+ canUpdate={canUpdate}
91
+ customLogo={menuLogo.display}
92
+ defaultLogo={menu.default}
93
+ hint={formatMessage({
94
+ id: 'Settings.application.customization.menu-logo.carousel-hint',
95
+ defaultMessage: 'Replace the logo in the main navigation',
96
+ })}
97
+ label={formatMessage({
98
+ id: 'Settings.application.customization.carousel.menu-logo.title',
99
+ defaultMessage: 'Menu logo',
100
+ })}
101
+ onChangeLogo={handleChangeMenuLogo}
102
+ onResetLogo={handleResetMenuLogo}
103
+ />
104
+ </GridItem>
105
+ <GridItem col={6} s={12}>
106
+ <LogoInput
107
+ canUpdate={canUpdate}
108
+ customLogo={authLogo.display}
109
+ defaultLogo={auth.default}
110
+ hint={formatMessage({
111
+ id: 'Settings.application.customization.auth-logo.carousel-hint',
112
+ defaultMessage: 'Replace the logo in the authentication pages',
113
+ })}
114
+ label={formatMessage({
115
+ id: 'Settings.application.customization.carousel.auth-logo.title',
116
+ defaultMessage: 'Auth logo',
117
+ })}
118
+ onChangeLogo={handleChangeAuthLogo}
119
+ onResetLogo={handleResetAuthLogo}
120
+ />
121
+ </GridItem>
122
+ </Grid>
123
+ </Box>
124
+ );
125
+ });
126
+
127
+ CustomizationInfos.defaultProps = {
128
+ canUpdate: false,
129
+ projectSettingsStored: null,
130
+ };
131
+
132
+ CustomizationInfos.propTypes = {
133
+ canUpdate: PropTypes.bool,
134
+ projectSettingsStored: PropTypes.shape({
135
+ menuLogo: PropTypes.shape({
136
+ url: PropTypes.string,
137
+ name: PropTypes.string,
138
+ }),
139
+ }),
140
+ };
141
+
142
+ export default CustomizationInfos;
@@ -5,6 +5,9 @@ const init = (initialState, projectSettingsStored) => {
5
5
  menuLogo: {
6
6
  display: projectSettingsStored.menuLogo,
7
7
  },
8
+ authLogo: {
9
+ display: projectSettingsStored.authLogo,
10
+ },
8
11
  });
9
12
 
10
13
  return copyInitialState;
@@ -15,6 +15,13 @@ const initialState = {
15
15
  isReset: false,
16
16
  },
17
17
  },
18
+ authLogo: {
19
+ display: null,
20
+ submit: {
21
+ rawFile: null,
22
+ isReset: false,
23
+ },
24
+ },
18
25
  };
19
26
 
20
27
  const reducer = (state = initialState, action) =>
@@ -25,6 +32,11 @@ const reducer = (state = initialState, action) =>
25
32
  draftState.menuLogo.submit.rawFile = action.value.rawFile;
26
33
  break;
27
34
  }
35
+ case 'SET_CUSTOM_AUTH_LOGO': {
36
+ draftState.authLogo.display = action.value;
37
+ draftState.authLogo.submit.rawFile = action.value.rawFile;
38
+ break;
39
+ }
28
40
  case 'RESET_CUSTOM_MENU_LOGO': {
29
41
  draftState.menuLogo.display = null;
30
42
  draftState.menuLogo.submit = {
@@ -33,6 +45,14 @@ const reducer = (state = initialState, action) =>
33
45
  };
34
46
  break;
35
47
  }
48
+ case 'RESET_CUSTOM_AUTH_LOGO': {
49
+ draftState.authLogo.display = null;
50
+ draftState.authLogo.submit = {
51
+ rawFile: null,
52
+ isReset: true,
53
+ };
54
+ break;
55
+ }
36
56
  default: {
37
57
  return draftState;
38
58
  }
@@ -6,12 +6,19 @@ import { IconButton } from '@strapi/design-system/IconButton';
6
6
  import { Box } from '@strapi/design-system/Box';
7
7
  import Plus from '@strapi/icons/Plus';
8
8
  import Refresh from '@strapi/icons/Refresh';
9
- import reducer, { initialState } from './reducer';
10
9
  import LogoModalStepper from '../LogoModalStepper';
11
- import { SIZE, DIMENSION } from '../../utils/constants';
10
+ import reducer, { initialState } from './reducer';
12
11
  import stepper from './stepper';
13
12
 
14
- const LogoInput = ({ customLogo, defaultLogo, onChangeLogo, onResetMenuLogo }) => {
13
+ const LogoInput = ({
14
+ canUpdate,
15
+ customLogo,
16
+ defaultLogo,
17
+ hint,
18
+ label,
19
+ onChangeLogo,
20
+ onResetLogo,
21
+ }) => {
15
22
  const [{ currentStep }, dispatch] = useReducer(reducer, initialState);
16
23
  const { Component, next, prev, modalTitle } = stepper[currentStep] || {};
17
24
  const { formatMessage } = useIntl();
@@ -26,19 +33,9 @@ const LogoInput = ({ customLogo, defaultLogo, onChangeLogo, onResetMenuLogo }) =
26
33
  return (
27
34
  <>
28
35
  <CarouselInput
29
- label={formatMessage({
30
- id: 'Settings.application.customization.carousel.title',
31
- defaultMessage: 'Logo',
32
- })}
36
+ label={label}
33
37
  selectedSlide={0}
34
- hint={formatMessage(
35
- {
36
- id: 'Settings.application.customization.carousel-hint',
37
- defaultMessage:
38
- 'Change the admin panel logo (Max dimension: {dimension}x{dimension}, Max file size: {size}KB)',
39
- },
40
- { size: SIZE, dimension: DIMENSION }
41
- )}
38
+ hint={hint}
42
39
  // Carousel is used here for a single media,
43
40
  // we don't need previous and next labels but these props are required
44
41
  previousLabel=""
@@ -49,6 +46,7 @@ const LogoInput = ({ customLogo, defaultLogo, onChangeLogo, onResetMenuLogo }) =
49
46
  actions={
50
47
  <CarouselActions>
51
48
  <IconButton
49
+ disabled={!canUpdate}
52
50
  onClick={() => goTo(customLogo ? 'pending' : 'upload')}
53
51
  label={formatMessage({
54
52
  id: 'Settings.application.customization.carousel.change-action',
@@ -58,7 +56,8 @@ const LogoInput = ({ customLogo, defaultLogo, onChangeLogo, onResetMenuLogo }) =
58
56
  />
59
57
  {customLogo && (
60
58
  <IconButton
61
- onClick={onResetMenuLogo}
59
+ disabled={!canUpdate}
60
+ onClick={onResetLogo}
62
61
  label={formatMessage({
63
62
  id: 'Settings.application.customization.carousel.reset-action',
64
63
  defaultMessage: 'Reset logo',
@@ -102,17 +101,22 @@ const LogoInput = ({ customLogo, defaultLogo, onChangeLogo, onResetMenuLogo }) =
102
101
  };
103
102
 
104
103
  LogoInput.defaultProps = {
104
+ canUpdate: false,
105
105
  customLogo: null,
106
+ hint: null,
106
107
  };
107
108
 
108
109
  LogoInput.propTypes = {
110
+ canUpdate: PropTypes.bool,
109
111
  customLogo: PropTypes.shape({
110
112
  url: PropTypes.string,
111
113
  name: PropTypes.string,
112
114
  }),
115
+ label: PropTypes.string.isRequired,
116
+ hint: PropTypes.string,
113
117
  defaultLogo: PropTypes.string.isRequired,
114
118
  onChangeLogo: PropTypes.func.isRequired,
115
- onResetMenuLogo: PropTypes.func.isRequired,
119
+ onResetLogo: PropTypes.func.isRequired,
116
120
  };
117
121
 
118
122
  export default LogoInput;
@@ -5,8 +5,8 @@ import {
5
5
  useAppInfos,
6
6
  SettingsPageTitle,
7
7
  useFocusWhenNavigate,
8
- CheckPermissions,
9
8
  useNotification,
9
+ useRBAC,
10
10
  useTracking,
11
11
  } from '@strapi/helper-plugin';
12
12
  import { HeaderLayout, Layout, ContentLayout } from '@strapi/design-system/Layout';
@@ -19,13 +19,12 @@ import { Button } from '@strapi/design-system/Button';
19
19
  import { Link } from '@strapi/design-system/v2/Link';
20
20
  import ExternalLink from '@strapi/icons/ExternalLink';
21
21
  import Check from '@strapi/icons/Check';
22
+ import adminPermissions from '../../../../permissions';
22
23
  import { useConfigurations } from '../../../../hooks';
23
- import Form from './components/Form';
24
+ import CustomizationInfos from './components/CustomizationInfos';
24
25
  import { fetchProjectSettings, postProjectSettings } from './utils/api';
25
26
  import getFormData from './utils/getFormData';
26
27
 
27
- const permissions = [{ action: 'admin::project-settings.update', subject: null }];
28
-
29
28
  const ApplicationInfosPage = () => {
30
29
  const inputsRef = useRef();
31
30
  const toggleNotification = useNotification();
@@ -37,30 +36,52 @@ const ApplicationInfosPage = () => {
37
36
  const { shouldUpdateStrapi, latestStrapiReleaseTag, strapiVersion } = appInfos;
38
37
  const { updateProjectSettings } = useConfigurations();
39
38
 
40
- const { data } = useQuery('project-settings', fetchProjectSettings);
39
+ const {
40
+ allowedActions: { canRead, canUpdate },
41
+ } = useRBAC(adminPermissions.settings['project-settings']);
42
+ const canSubmit = canRead && canUpdate;
43
+
44
+ const { data } = useQuery('project-settings', fetchProjectSettings, { enabled: canRead });
41
45
 
42
46
  const currentPlan = appInfos.communityEdition
43
47
  ? 'app.components.UpgradePlanModal.text-ce'
44
48
  : 'app.components.UpgradePlanModal.text-ee';
45
49
 
46
50
  const submitMutation = useMutation((body) => postProjectSettings(body), {
47
- async onSuccess({ menuLogo }) {
51
+ async onSuccess({ menuLogo, authLogo }) {
48
52
  await queryClient.invalidateQueries('project-settings', { refetchActive: true });
49
- updateProjectSettings({ menuLogo: menuLogo?.url });
53
+ updateProjectSettings({ menuLogo: menuLogo?.url, authLogo: authLogo?.url });
50
54
  },
51
55
  });
52
56
 
53
- const handleSubmit = () => {
57
+ const handleSubmit = (e) => {
58
+ e.preventDefault();
59
+
60
+ if (!canUpdate) return;
61
+
54
62
  const inputValues = inputsRef.current.getValues();
55
63
  const formData = getFormData(inputValues);
56
64
 
57
65
  submitMutation.mutate(formData, {
58
66
  onSuccess() {
59
- const { menuLogo } = inputValues;
67
+ const { menuLogo, authLogo } = inputValues;
60
68
 
61
69
  if (menuLogo.rawFile) {
62
- trackUsage('didChangeLogo');
70
+ trackUsage('didChangeLogo', {
71
+ logo: 'menu',
72
+ });
63
73
  }
74
+
75
+ if (authLogo.rawFile) {
76
+ trackUsage('didChangeLogo', {
77
+ logo: 'auth',
78
+ });
79
+ }
80
+
81
+ toggleNotification({
82
+ type: 'success',
83
+ message: formatMessage({ id: 'app', defaultMessage: 'Saved' }),
84
+ });
64
85
  },
65
86
  onError() {
66
87
  toggleNotification({
@@ -75,30 +96,33 @@ const ApplicationInfosPage = () => {
75
96
  <Layout>
76
97
  <SettingsPageTitle name="Application" />
77
98
  <Main>
78
- <HeaderLayout
79
- title={formatMessage({ id: 'Settings.application.title', defaultMessage: 'Overview' })}
80
- subtitle={formatMessage({
81
- id: 'Settings.application.description',
82
- defaultMessage: 'Administration panel’s global information',
83
- })}
84
- primaryAction={
85
- <Button onClick={handleSubmit} startIcon={<Check />}>
86
- {formatMessage({ id: 'global.save', defaultMessage: 'Save' })}
87
- </Button>
88
- }
89
- />
90
- <ContentLayout>
91
- <Stack spacing={6}>
92
- <Box
93
- hasRadius
94
- background="neutral0"
95
- shadow="tableShadow"
96
- paddingTop={6}
97
- paddingBottom={6}
98
- paddingRight={7}
99
- paddingLeft={7}
100
- >
101
- <Stack spacing={5}>
99
+ <form onSubmit={handleSubmit}>
100
+ <HeaderLayout
101
+ title={formatMessage({ id: 'Settings.application.title', defaultMessage: 'Overview' })}
102
+ subtitle={formatMessage({
103
+ id: 'Settings.application.description',
104
+ defaultMessage: 'Administration panel’s global information',
105
+ })}
106
+ primaryAction={
107
+ canSubmit && (
108
+ <Button type="submit" startIcon={<Check />}>
109
+ {formatMessage({ id: 'global.save', defaultMessage: 'Save' })}
110
+ </Button>
111
+ )
112
+ }
113
+ />
114
+ <ContentLayout>
115
+ <Stack spacing={6}>
116
+ <Stack
117
+ spacing={5}
118
+ hasRadius
119
+ background="neutral0"
120
+ shadow="tableShadow"
121
+ paddingTop={6}
122
+ paddingBottom={6}
123
+ paddingRight={7}
124
+ paddingLeft={7}
125
+ >
102
126
  <Typography variant="delta" as="h3">
103
127
  {formatMessage({
104
128
  id: 'global.details',
@@ -187,14 +211,16 @@ const ApplicationInfosPage = () => {
187
211
  <Typography as="p">{appInfos.nodeVersion}</Typography>
188
212
  </Box>
189
213
  </Stack>
190
- </Box>
191
- {data && (
192
- <CheckPermissions permissions={permissions}>
193
- <Form ref={inputsRef} projectSettingsStored={data} />
194
- </CheckPermissions>
195
- )}
196
- </Stack>
197
- </ContentLayout>
214
+ {canRead && data && (
215
+ <CustomizationInfos
216
+ canUpdate={canUpdate}
217
+ ref={inputsRef}
218
+ projectSettingsStored={data}
219
+ />
220
+ )}
221
+ </Stack>
222
+ </ContentLayout>
223
+ </form>
198
224
  </Main>
199
225
  </Layout>
200
226
  );
@@ -1,14 +1,20 @@
1
- import { axiosInstance } from '../../../../../core/utils';
1
+ import { getFetchClient } from '@strapi/helper-plugin';
2
2
  import prefixAllUrls from './prefixAllUrls';
3
3
 
4
4
  const fetchProjectSettings = async () => {
5
- const { data } = await axiosInstance.get('/admin/project-settings');
5
+ const { get } = getFetchClient();
6
+ const { data } = await get('/admin/project-settings');
6
7
 
7
8
  return prefixAllUrls(data);
8
9
  };
9
10
 
10
11
  const postProjectSettings = async (body) => {
11
- const { data } = await axiosInstance.post('/admin/project-settings', body);
12
+ const { post } = getFetchClient();
13
+ const { data } = await post('/admin/project-settings', body, {
14
+ headers: {
15
+ 'Content-Type': 'multipart/form-data',
16
+ },
17
+ });
12
18
 
13
19
  return prefixAllUrls(data);
14
20
  };
@@ -1,13 +1,16 @@
1
- import { axiosInstance } from '../../../../../../core/utils';
1
+ import { getFetchClient } from '@strapi/helper-plugin';
2
2
 
3
3
  const fetchUser = async (id) => {
4
- const { data } = await axiosInstance.get(`/admin/users/${id}`);
4
+ const { get } = getFetchClient();
5
+ const { data } = await get(`/admin/users/${id}`);
5
6
 
6
7
  return data.data;
7
8
  };
8
9
 
9
10
  const putUser = async (id, body) => {
10
- const { data } = await axiosInstance.put(`/admin/users/${id}`, body);
11
+ const { put } = getFetchClient();
12
+
13
+ const { data } = await put(`/admin/users/${id}`, body);
11
14
 
12
15
  return data.data;
13
16
  };
@@ -15,12 +15,17 @@ import { Stack } from '@strapi/design-system/Stack';
15
15
  import { Typography } from '@strapi/design-system/Typography';
16
16
 
17
17
  import { Formik } from 'formik';
18
- import { Form, GenericInput, useNotification, useOverlayBlocker } from '@strapi/helper-plugin';
18
+ import {
19
+ Form,
20
+ GenericInput,
21
+ useNotification,
22
+ useOverlayBlocker,
23
+ useFetchClient,
24
+ } from '@strapi/helper-plugin';
19
25
  import { useQueryClient, useMutation } from 'react-query';
20
26
  import formDataModel from 'ee_else_ce/pages/SettingsPage/pages/Users/ListPage/ModalForm/utils/formDataModel';
21
27
  import roleSettingsForm from 'ee_else_ce/pages/SettingsPage/pages/Users/ListPage/ModalForm/utils/roleSettingsForm';
22
28
  import MagicLink from 'ee_else_ce/pages/SettingsPage/pages/Users/components/MagicLink';
23
- import { axiosInstance } from '../../../../../../core/utils';
24
29
  import SelectRoles from '../../components/SelectRoles';
25
30
  import layout from './utils/layout';
26
31
  import schema from './utils/schema';
@@ -34,9 +39,10 @@ const ModalForm = ({ queryName, onToggle }) => {
34
39
  const { formatMessage } = useIntl();
35
40
  const toggleNotification = useNotification();
36
41
  const { lockApp, unlockApp } = useOverlayBlocker();
42
+ const { post } = useFetchClient();
37
43
  const postMutation = useMutation(
38
44
  (body) => {
39
- return axiosInstance.post('/admin/users', body);
45
+ return post('/admin/users', body);
40
46
  },
41
47
  {
42
48
  async onSuccess({ data }) {
@@ -18,7 +18,7 @@ import { useIntl } from 'react-intl';
18
18
  import { useMutation, useQuery, useQueryClient } from 'react-query';
19
19
  import adminPermissions from '../../../../../permissions';
20
20
  import TableRows from './DynamicTable/TableRows';
21
- import Filters from './Filters';
21
+ import Filters from '../../../components/Filters';
22
22
  import ModalForm from './ModalForm';
23
23
  import PaginationFooter from './PaginationFooter';
24
24
  import { deleteData, fetchData } from './utils/api';
@@ -1,9 +1,10 @@
1
- import { axiosInstance } from '../../../../../../core/utils';
1
+ import { getFetchClient } from '@strapi/helper-plugin';
2
2
 
3
3
  const fetchData = async (search, notify) => {
4
+ const { get } = getFetchClient();
4
5
  const {
5
6
  data: { data },
6
- } = await axiosInstance.get(`/admin/users${search}`);
7
+ } = await get(`/admin/users${search}`);
7
8
 
8
9
  notify();
9
10
 
@@ -11,7 +12,9 @@ const fetchData = async (search, notify) => {
11
12
  };
12
13
 
13
14
  const deleteData = async (ids) => {
14
- await axiosInstance.post('/admin/users/batch-delete', { ids });
15
+ const { post } = getFetchClient();
16
+
17
+ await post('/admin/users/batch-delete', { ids });
15
18
  };
16
19
 
17
20
  export { deleteData, fetchData };
@@ -5,7 +5,7 @@ import { Select, Option } from '@strapi/design-system/Select';
5
5
  import { useQuery } from 'react-query';
6
6
  import styled, { keyframes } from 'styled-components';
7
7
  import LoadingIcon from '@strapi/icons/Loader';
8
- import { axiosInstance } from '../../../../../../core/utils';
8
+ import { getFetchClient } from '@strapi/helper-plugin';
9
9
 
10
10
  const rotation = keyframes`
11
11
  from {
@@ -27,7 +27,8 @@ const Loader = () => (
27
27
  );
28
28
 
29
29
  const fetchData = async () => {
30
- const { data } = await axiosInstance.get('/admin/roles');
30
+ const { get } = getFetchClient();
31
+ const { data } = await get('/admin/roles');
31
32
 
32
33
  return data.data;
33
34
  };
@@ -118,7 +118,7 @@ const EventInput = ({ isDraftAndPublish }) => {
118
118
  title={formatMessage({
119
119
  id: 'Settings.webhooks.event.publish-tooltip',
120
120
  defaultMessage:
121
- 'This event only exists for contents with Draft/Publish system enabled',
121
+ 'This event only exists for content with draft & publish enabled',
122
122
  })}
123
123
  >
124
124
  <Typography variant="sigma" textColor="neutral600">
@@ -11,12 +11,12 @@ import {
11
11
  to,
12
12
  useNotification,
13
13
  useOverlayBlocker,
14
+ useFetchClient,
14
15
  } from '@strapi/helper-plugin';
15
16
  import { Main } from '@strapi/design-system/Main';
16
17
  import { useMutation, useQuery, useQueryClient } from 'react-query';
17
18
  import { useHistory, useRouteMatch } from 'react-router-dom';
18
19
  import { useModels } from '../../../../../hooks';
19
- import { axiosInstance } from '../../../../../core/utils';
20
20
  import WebhookForm from './components/WebhookForm';
21
21
  import cleanData from './utils/formatData';
22
22
 
@@ -30,6 +30,7 @@ const EditView = () => {
30
30
  const toggleNotification = useNotification();
31
31
  const queryClient = useQueryClient();
32
32
  const { isLoading: isLoadingForModels, collectionTypes } = useModels();
33
+ const { post } = useFetchClient();
33
34
 
34
35
  const isCreating = id === 'create';
35
36
 
@@ -64,7 +65,7 @@ const EditView = () => {
64
65
  data: triggerResponse,
65
66
  isIdle: isTriggerIdle,
66
67
  mutate,
67
- } = useMutation(() => axiosInstance.post(`/admin/webhooks/${id}/trigger`));
68
+ } = useMutation(() => post(`/admin/webhooks/${id}/trigger`));
68
69
 
69
70
  const triggerWebhook = () =>
70
71
  mutate(null, {
@@ -57,17 +57,6 @@ const defaultRoutes = [
57
57
  to: '/settings/users/:id',
58
58
  exact: true,
59
59
  },
60
- {
61
- async Component() {
62
- const component = await import(
63
- /* webpackChunkName: "admin-audit-logs" */ '../pages/AuditLogs/ProtectedListPage'
64
- );
65
-
66
- return component;
67
- },
68
- to: '/settings/audit-logs',
69
- exact: true,
70
- },
71
60
  {
72
61
  async Component() {
73
62
  const component = await import(
@@ -87,6 +87,10 @@ const permissions = {
87
87
  update: [{ action: 'admin::api-tokens.update', subject: null }],
88
88
  regenerate: [{ action: 'admin::api-tokens.regenerate', subject: null }],
89
89
  },
90
+ 'project-settings': {
91
+ read: [{ action: 'admin::project-settings.read', subject: null }],
92
+ update: [{ action: 'admin::project-settings.update', subject: null }],
93
+ },
90
94
  },
91
95
  };
92
96