@strapi/admin 4.2.0-beta.2 → 4.2.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 (217) hide show
  1. package/admin/src/app.js +4 -7
  2. package/admin/src/assets/images/homepage-logo.png +0 -0
  3. package/admin/src/components/AutoReloadOverlayBlockerProvider/Blocker.js +2 -6
  4. package/admin/src/components/ConfigurationsProvider/index.js +51 -0
  5. package/admin/src/components/ConfigurationsProvider/reducer.js +28 -0
  6. package/admin/src/components/GuidedTour/Homepage/index.js +1 -2
  7. package/admin/src/components/GuidedTour/Modal/components/Stepper.js +1 -2
  8. package/admin/src/components/LeftMenu/index.js +19 -7
  9. package/admin/src/components/Notifications/Notification/index.js +2 -2
  10. package/admin/src/components/Providers/index.js +8 -4
  11. package/admin/src/components/UnauthenticatedLogo/index.js +4 -2
  12. package/admin/src/components/UpgradePlanModal/index.js +6 -2
  13. package/admin/src/content-manager/components/DynamicZone/components/ComponentPicker/Category/ComponentCard/index.js +1 -1
  14. package/admin/src/content-manager/components/SelectMany/ListItem.js +1 -2
  15. package/admin/src/content-manager/components/SelectWrapper/index.js +8 -7
  16. package/admin/src/content-manager/components/SelectWrapper/utils/getSelectStyles.js +1 -1
  17. package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +2 -2
  18. package/admin/src/content-manager/components/Wysiwyg/Editor.js +2 -0
  19. package/admin/src/content-manager/pages/App/LeftMenu/index.js +8 -7
  20. package/admin/src/content-manager/pages/EditSettingsView/components/ComponentFieldList.js +1 -1
  21. package/admin/src/content-manager/pages/EditSettingsView/components/LinkToCTB.js +1 -2
  22. package/admin/src/content-manager/pages/EditSettingsView/index.js +1 -2
  23. package/admin/src/content-manager/pages/EditView/Header/index.js +3 -3
  24. package/admin/src/content-manager/pages/EditView/index.js +1 -4
  25. package/admin/src/content-manager/pages/ListSettingsView/index.js +1 -2
  26. package/admin/src/content-manager/pages/ListView/index.js +1 -1
  27. package/admin/src/content-manager/pages/NoContentType/index.js +1 -2
  28. package/admin/src/hooks/useFetchMarketplaceProviders/index.js +23 -0
  29. package/admin/src/hooks/useFetchMarketplaceProviders/utils/api.js +11 -0
  30. package/admin/src/pages/Admin/index.js +5 -15
  31. package/admin/src/pages/App/index.js +9 -18
  32. package/admin/src/pages/AuthPage/components/ForgotPassword/index.js +1 -2
  33. package/admin/src/pages/AuthPage/components/ForgotPasswordSuccess/index.js +1 -1
  34. package/admin/src/pages/AuthPage/components/Login/BaseLogin.js +1 -2
  35. package/admin/src/pages/AuthPage/components/Oops/index.js +1 -2
  36. package/admin/src/pages/AuthPage/components/Register/index.js +12 -12
  37. package/admin/src/pages/AuthPage/components/ResetPassword/index.js +3 -4
  38. package/admin/src/pages/HomePage/ContentBlocks.js +15 -2
  39. package/admin/src/pages/HomePage/HomeHeader.js +2 -2
  40. package/admin/src/pages/HomePage/SocialLinks.js +4 -3
  41. package/admin/src/pages/InternalErrorPage/index.js +1 -2
  42. package/admin/src/pages/MarketplacePage/components/{EmptyPluginSearch/EmptyPluginGrid.js → EmptyNpmPackageSearch/EmptyNpmPackageGrid.js} +1 -1
  43. package/admin/src/pages/MarketplacePage/components/{EmptyPluginSearch → EmptyNpmPackageSearch}/index.js +6 -4
  44. package/admin/src/pages/MarketplacePage/components/{PluginCard → NpmPackageCard}/InstallPluginButton.js +0 -0
  45. package/admin/src/pages/MarketplacePage/components/{PluginCard → NpmPackageCard}/index.js +26 -13
  46. package/admin/src/pages/MarketplacePage/components/NpmPackagesGrid/index.js +42 -0
  47. package/admin/src/pages/MarketplacePage/components/PageHeader/index.js +14 -6
  48. package/admin/src/pages/MarketplacePage/index.js +99 -37
  49. package/admin/src/pages/NotFoundPage/index.js +1 -2
  50. package/admin/src/pages/SettingsPage/components/SettingsNav/index.js +5 -4
  51. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +1 -1
  52. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js +1 -1
  53. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +1 -1
  54. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/index.js +85 -0
  55. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/init.js +13 -0
  56. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/reducer.js +43 -0
  57. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/index.js +118 -0
  58. package/admin/src/pages/{App → SettingsPage/pages/ApplicationInfosPage/components/LogoInput}/reducer.js +13 -7
  59. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/stepper.js +25 -0
  60. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/AddLogoDialog.js +67 -0
  61. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/FromComputerForm.js +176 -0
  62. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/FromUrlForm.js +82 -0
  63. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/ImageCardAsset.js +51 -0
  64. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/PendingLogoDialog.js +97 -0
  65. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/index.js +85 -0
  66. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/reducer.js +28 -0
  67. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/index.js +155 -87
  68. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/api.js +16 -0
  69. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/constants.js +3 -0
  70. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/getFormData.js +17 -0
  71. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/parseFileMetadatas.js +76 -0
  72. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/prefixAllUrls.js +17 -0
  73. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/urlToFile.js +21 -0
  74. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/index.js +1 -1
  75. package/admin/src/pages/SettingsPage/pages/Users/EditPage/index.js +1 -1
  76. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/index.js +1 -2
  77. package/admin/src/pages/SettingsPage/pages/Webhooks/ListView/index.js +1 -1
  78. package/admin/src/reducers.js +2 -4
  79. package/admin/src/translations/en.json +33 -3
  80. package/admin/src/translations/pl.json +264 -12
  81. package/admin/src/translations/vi.json +17 -17
  82. package/build/1856.6a94980b.chunk.js +172 -0
  83. package/build/2077.5456ccd1.chunk.js +194 -0
  84. package/build/2758.9475712b.chunk.js +162 -0
  85. package/build/2912.dd031292.chunk.js +253 -0
  86. package/build/4715.4588fdf5.chunk.js +385 -0
  87. package/build/4800.d3ebc81d.chunk.js +1 -0
  88. package/build/4982.c57c5675.chunk.js +308 -0
  89. package/build/7197.ed8d6752.chunk.js +113 -0
  90. package/build/7589.577cf729.chunk.js +194 -0
  91. package/build/{7393.8ae60738.chunk.js → 7757.f6eb5e92.chunk.js} +89 -87
  92. package/build/7841.9e9cf739.chunk.js +253 -0
  93. package/build/8681.aec05472.chunk.js +163 -0
  94. package/build/9066.2847fdff.chunk.js +101 -0
  95. package/build/9115.abdf4e3b.chunk.js +1 -0
  96. package/build/9158.e48d88af.chunk.js +503 -0
  97. package/build/{7191.3bde3cbf.chunk.js → 9298.cb3b6bc1.chunk.js} +112 -113
  98. package/build/9420.ba035f29.chunk.js +508 -0
  99. package/build/948.d64fb515.chunk.js +2 -0
  100. package/build/Admin-authenticatedApp.e7ed0550.chunk.js +80 -0
  101. package/build/Admin_homePage.8c00145e.chunk.js +71 -0
  102. package/build/Admin_marketplace.a88d5bda.chunk.js +11 -0
  103. package/build/Admin_pluginsPage.e895d79f.chunk.js +1 -0
  104. package/build/{Admin_profilePage.62c203ad.chunk.js → Admin_profilePage.33cfed9b.chunk.js} +2 -2
  105. package/build/Admin_settingsPage.fe33e0a2.chunk.js +180 -0
  106. package/build/admin-edit-roles-page.e77a2acc.chunk.js +1 -0
  107. package/build/admin-edit-users.4c49fe98.chunk.js +11 -0
  108. package/build/admin-users.b89adf82.chunk.js +12 -0
  109. package/build/api-tokens-create-page.618b3e40.chunk.js +1 -0
  110. package/build/api-tokens-edit-page.8d19dfe1.chunk.js +1 -0
  111. package/build/api-tokens-list-page.274e1c80.chunk.js +15 -0
  112. package/build/{codemirror-css.b467b1de.chunk.js → codemirror-css.98490df3.chunk.js} +2 -2
  113. package/build/{codemirror-javacript.41bdefda.chunk.js → codemirror-javacript.cafbda9c.chunk.js} +1 -1
  114. package/build/codemirror-theme.b3c64617.chunk.js +34 -0
  115. package/build/content-manager.04b93497.chunk.js +1204 -0
  116. package/build/content-type-builder.b3139cb1.chunk.js +141 -0
  117. package/build/{cropper-css.ecc0d670.chunk.js → cropper-css.0055cd53.chunk.js} +2 -2
  118. package/build/email-settings-page.4ae595f6.chunk.js +103 -0
  119. package/build/en-json.0a5ba154.chunk.js +1 -0
  120. package/build/fb376b132d18bf4522ca.png +0 -0
  121. package/build/{fontawesome-css-all.04f33619.chunk.js → fontawesome-css-all.b88d464e.chunk.js} +3 -3
  122. package/build/{fontawesome-css.477ba714.chunk.js → fontawesome-css.59dc4459.chunk.js} +2 -2
  123. package/build/highlight.js.9d8ef460.chunk.js +86 -0
  124. package/build/i18n-settings-page.bdac3c7b.chunk.js +101 -0
  125. package/build/index.html +1 -1
  126. package/build/main.3257934a.js +8404 -0
  127. package/build/pl-json.f65302c2.chunk.js +1 -0
  128. package/build/{runtime~main.a32b12c8.js → runtime~main.de49adfd.js} +1 -1
  129. package/build/sso-settings-page.0b4d2106.chunk.js +1 -0
  130. package/build/upload-settings.cadfd452.chunk.js +101 -0
  131. package/build/upload-translation-ca-json.79159984.chunk.js +1 -0
  132. package/build/upload.fbc65439.chunk.js +105 -0
  133. package/build/users-advanced-settings-page.646b6f29.chunk.js +101 -0
  134. package/build/users-email-settings-page.8b561ea3.chunk.js +1 -0
  135. package/build/users-providers-settings-page.82141ace.chunk.js +1 -0
  136. package/build/users-roles-settings-page.28bf6bdc.chunk.js +30 -0
  137. package/build/vi-json.bf3424be.chunk.js +1 -0
  138. package/build/webhook-edit-page.ca670f8d.chunk.js +23 -0
  139. package/build/webhook-list-page.7057f1e8.chunk.js +133 -0
  140. package/ee/admin/pages/AuthPage/components/Providers/index.js +1 -1
  141. package/ee/admin/pages/SettingsPage/pages/Roles/CreatePage/index.js +1 -1
  142. package/ee/server/controllers/user.js +4 -0
  143. package/index.js +239 -53
  144. package/package.json +8 -12
  145. package/scripts/build.js +3 -17
  146. package/server/config/admin-actions.js +14 -0
  147. package/server/controllers/admin.js +29 -12
  148. package/server/controllers/user.js +4 -0
  149. package/server/policies/index.js +0 -1
  150. package/server/routes/admin.js +28 -9
  151. package/server/routes/serve-admin-panel.js +1 -1
  152. package/server/services/index.js +1 -0
  153. package/server/services/permission/permissions-manager/sanitize.js +22 -0
  154. package/server/services/project-settings.js +173 -0
  155. package/server/services/user.js +1 -1
  156. package/server/utils/index.d.ts +2 -0
  157. package/server/validation/project-settings.js +39 -0
  158. package/webpack.config.js +5 -28
  159. package/admin/src/content-manager/components/DynamicComponentCard/index.js +0 -43
  160. package/admin/src/pages/App/constants.js +0 -1
  161. package/admin/src/tsconfig.json +0 -10
  162. package/build/1856.521a99fd.chunk.js +0 -172
  163. package/build/20.cf744c35.chunk.js +0 -308
  164. package/build/2077.51485bfb.chunk.js +0 -194
  165. package/build/2135.95ee6de1.chunk.js +0 -162
  166. package/build/2524.688d0355.chunk.js +0 -1
  167. package/build/2897.8e7d5853.chunk.js +0 -184
  168. package/build/2912.79c2b3c8.chunk.js +0 -253
  169. package/build/2a9e9ef5c4c775bb7c7b.png +0 -0
  170. package/build/4073.f3936352.chunk.js +0 -1
  171. package/build/4715.77e04177.chunk.js +0 -385
  172. package/build/5232.928fea74.chunk.js +0 -989
  173. package/build/6229.26d93336.chunk.js +0 -194
  174. package/build/6281.f10a7e3a.chunk.js +0 -1
  175. package/build/6404.80bf5858.chunk.js +0 -506
  176. package/build/7009.79fce86d.chunk.js +0 -164
  177. package/build/7841.f0e7d629.chunk.js +0 -253
  178. package/build/7863.c1938f3f.chunk.js +0 -112
  179. package/build/9066.118ecccd.chunk.js +0 -101
  180. package/build/Admin-authenticatedApp.1f76af8f.chunk.js +0 -80
  181. package/build/Admin_homePage.8b391120.chunk.js +0 -71
  182. package/build/Admin_marketplace.21730109.chunk.js +0 -11
  183. package/build/Admin_pluginsPage.788fb2f6.chunk.js +0 -1
  184. package/build/Admin_settingsPage.9ce20f16.chunk.js +0 -170
  185. package/build/admin-edit-roles-page.75380ed4.chunk.js +0 -1
  186. package/build/admin-edit-users.05f7f389.chunk.js +0 -10
  187. package/build/admin-users.e03db115.chunk.js +0 -11
  188. package/build/api-tokens-create-page.c44e0c62.chunk.js +0 -1
  189. package/build/api-tokens-edit-page.30d0924d.chunk.js +0 -1
  190. package/build/api-tokens-list-page.6049cd23.chunk.js +0 -15
  191. package/build/codemirror-theme.cf9f9eb6.chunk.js +0 -34
  192. package/build/content-manager.2f0f9b15.chunk.js +0 -1204
  193. package/build/content-type-builder.ce7b7f42.chunk.js +0 -141
  194. package/build/email-settings-page.f67d13b2.chunk.js +0 -103
  195. package/build/en-json.3e1a222e.chunk.js +0 -1
  196. package/build/highlight.js.3381ffc3.chunk.js +0 -86
  197. package/build/i18n-settings-page.6b67cb75.chunk.js +0 -101
  198. package/build/main.e6045245.js +0 -7909
  199. package/build/pl-json.94f05d2c.chunk.js +0 -1
  200. package/build/sso-settings-page.e9034e22.chunk.js +0 -1
  201. package/build/upload-settings.3db55de0.chunk.js +0 -101
  202. package/build/upload.070c189b.chunk.js +0 -105
  203. package/build/users-advanced-settings-page.a23cda17.chunk.js +0 -101
  204. package/build/users-email-settings-page.0a096388.chunk.js +0 -1
  205. package/build/users-providers-settings-page.bfe7755a.chunk.js +0 -1
  206. package/build/users-roles-settings-page.c01bec1d.chunk.js +0 -30
  207. package/build/vi-json.3d14e91e.chunk.js +0 -1
  208. package/build/webhook-edit-page.d457087d.chunk.js +0 -23
  209. package/build/webhook-list-page.a4217ff2.chunk.js +0 -133
  210. package/server/policies/isTelemetryEnabled.js +0 -16
  211. package/utils/create-cache-dir.js +0 -161
  212. package/utils/get-custom-app-config-file.js +0 -23
  213. package/utils/get-custom-webpack-config.js +0 -38
  214. package/utils/get-plugins-path.js +0 -26
  215. package/utils/index.js +0 -13
  216. package/utils/should-build-admin.js +0 -52
  217. package/utils/watch-admin-files.js +0 -59
@@ -1,26 +1,76 @@
1
- import React from 'react';
1
+ import React, { useRef } from 'react';
2
+ import { useQuery, useMutation, useQueryClient } from 'react-query';
2
3
  import { useIntl } from 'react-intl';
3
- import { useAppInfos, SettingsPageTitle, useFocusWhenNavigate } from '@strapi/helper-plugin';
4
+ import {
5
+ useAppInfos,
6
+ SettingsPageTitle,
7
+ useFocusWhenNavigate,
8
+ CheckPermissions,
9
+ useNotification,
10
+ useTracking,
11
+ } from '@strapi/helper-plugin';
4
12
  import { HeaderLayout, Layout, ContentLayout } from '@strapi/design-system/Layout';
5
13
  import { Main } from '@strapi/design-system/Main';
6
14
  import { Box } from '@strapi/design-system/Box';
7
15
  import { Grid, GridItem } from '@strapi/design-system/Grid';
8
16
  import { Typography } from '@strapi/design-system/Typography';
9
-
10
17
  import { Stack } from '@strapi/design-system/Stack';
11
- import { Link } from '@strapi/design-system/Link';
18
+ import { Button } from '@strapi/design-system/Button';
19
+ import { Link } from '@strapi/design-system/v2/Link';
12
20
  import ExternalLink from '@strapi/icons/ExternalLink';
21
+ import Check from '@strapi/icons/Check';
22
+ import { useConfigurations } from '../../../../hooks';
23
+ import Form from './components/Form';
24
+ import { fetchProjectSettings, postProjectSettings } from './utils/api';
25
+ import getFormData from './utils/getFormData';
26
+
27
+ const permissions = [{ action: 'admin::project-settings.update', subject: null }];
13
28
 
14
29
  const ApplicationInfosPage = () => {
30
+ const inputsRef = useRef();
31
+ const toggleNotification = useNotification();
32
+ const { trackUsage } = useTracking();
15
33
  const { formatMessage } = useIntl();
34
+ const queryClient = useQueryClient();
16
35
  useFocusWhenNavigate();
17
36
  const appInfos = useAppInfos();
18
37
  const { shouldUpdateStrapi, latestStrapiReleaseTag, strapiVersion } = appInfos;
38
+ const { updateProjectSettings } = useConfigurations();
39
+
40
+ const { data } = useQuery('project-settings', fetchProjectSettings);
19
41
 
20
42
  const currentPlan = appInfos.communityEdition
21
43
  ? 'app.components.UpgradePlanModal.text-ce'
22
44
  : 'app.components.UpgradePlanModal.text-ee';
23
45
 
46
+ const submitMutation = useMutation(body => postProjectSettings(body), {
47
+ onSuccess: async ({ menuLogo }) => {
48
+ await queryClient.invalidateQueries('project-settings', { refetchActive: true });
49
+ updateProjectSettings({ menuLogo: menuLogo?.url });
50
+ },
51
+ });
52
+
53
+ const handleSubmit = () => {
54
+ const inputValues = inputsRef.current.getValues();
55
+ const formData = getFormData(inputValues);
56
+
57
+ submitMutation.mutate(formData, {
58
+ onSuccess: () => {
59
+ const { menuLogo } = inputValues;
60
+
61
+ if (menuLogo.rawFile) {
62
+ trackUsage('didChangeLogo');
63
+ }
64
+ },
65
+ onError: () => {
66
+ toggleNotification({
67
+ type: 'warning',
68
+ message: { id: 'notification.error', defaultMessage: 'An error occurred' },
69
+ });
70
+ },
71
+ });
72
+ };
73
+
24
74
  return (
25
75
  <Layout>
26
76
  <SettingsPageTitle name="Application" />
@@ -31,101 +81,119 @@ const ApplicationInfosPage = () => {
31
81
  id: 'Settings.application.description',
32
82
  defaultMessage: 'Administration panel’s global information',
33
83
  })}
84
+ primaryAction={
85
+ <Button onClick={handleSubmit} startIcon={<Check />}>
86
+ {formatMessage({ id: 'global.save', defaultMessage: 'Save' })}
87
+ </Button>
88
+ }
34
89
  />
35
90
  <ContentLayout>
36
- <Box
37
- hasRadius
38
- background="neutral0"
39
- shadow="tableShadow"
40
- paddingTop={7}
41
- paddingBottom={7}
42
- paddingRight={6}
43
- paddingLeft={6}
44
- >
45
- <Stack spacing={5}>
46
- <Typography variant="delta" as="h3">
47
- {formatMessage({
48
- id: 'global.details',
49
- defaultMessage: 'Details',
50
- })}
51
- </Typography>
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}>
102
+ <Typography variant="delta" as="h3">
103
+ {formatMessage({
104
+ id: 'global.details',
105
+ defaultMessage: 'Details',
106
+ })}
107
+ </Typography>
52
108
 
53
- <Grid paddingTop={1}>
54
- <GridItem col={6} s={12}>
55
- <Typography variant="sigma" textColor="neutral600">
56
- {formatMessage({
57
- id: 'Settings.application.strapiVersion',
58
- defaultMessage: 'strapi version',
59
- })}
60
- </Typography>
61
- <Typography as="p">v{strapiVersion}</Typography>
62
- <Link
63
- href={
64
- appInfos.communityEdition
65
- ? 'https://discord.strapi.io'
66
- : 'https://support.strapi.io/support/home'
67
- }
68
- endIcon={<ExternalLink />}
69
- >
70
- {formatMessage({
71
- id: 'Settings.application.get-help',
72
- defaultMessage: 'Get help',
73
- })}
74
- </Link>
75
- </GridItem>
76
- <GridItem col={6} s={12}>
77
- <Typography variant="sigma" textColor="neutral600">
78
- {formatMessage({
79
- id: 'Settings.application.edition-title',
80
- defaultMessage: 'current plan',
81
- })}
82
- </Typography>
83
- <Typography as="p">
84
- {formatMessage({
85
- id: currentPlan,
86
- defaultMessage: `${
87
- appInfos.communityEdition ? 'Community Edition' : 'Enterprise Edition'
88
- }`,
89
- })}
90
- </Typography>
91
- </GridItem>
92
- </Grid>
109
+ <Grid paddingTop={1}>
110
+ <GridItem col={6} s={12}>
111
+ <Typography variant="sigma" textColor="neutral600">
112
+ {formatMessage({
113
+ id: 'Settings.application.strapiVersion',
114
+ defaultMessage: 'strapi version',
115
+ })}
116
+ </Typography>
117
+ <Typography as="p">v{strapiVersion}</Typography>
118
+ <Link
119
+ href={
120
+ appInfos.communityEdition
121
+ ? 'https://discord.strapi.io'
122
+ : 'https://support.strapi.io/support/home'
123
+ }
124
+ isExternal
125
+ endIcon={<ExternalLink />}
126
+ >
127
+ {formatMessage({
128
+ id: 'Settings.application.get-help',
129
+ defaultMessage: 'Get help',
130
+ })}
131
+ </Link>
132
+ </GridItem>
133
+ <GridItem col={6} s={12}>
134
+ <Typography variant="sigma" textColor="neutral600">
135
+ {formatMessage({
136
+ id: 'Settings.application.edition-title',
137
+ defaultMessage: 'current plan',
138
+ })}
139
+ </Typography>
140
+ <Typography as="p">
141
+ {formatMessage({
142
+ id: currentPlan,
143
+ defaultMessage: `${
144
+ appInfos.communityEdition ? 'Community Edition' : 'Enterprise Edition'
145
+ }`,
146
+ })}
147
+ </Typography>
148
+ </GridItem>
149
+ </Grid>
93
150
 
94
- <Grid paddingTop={1}>
95
- <GridItem col={6} s={12}>
96
- {shouldUpdateStrapi && (
151
+ <Grid paddingTop={1}>
152
+ <GridItem col={6} s={12}>
153
+ {shouldUpdateStrapi && (
154
+ <Link
155
+ href={`https://github.com/strapi/strapi/releases/tag/${latestStrapiReleaseTag}`}
156
+ isExternal
157
+ endIcon={<ExternalLink />}
158
+ >
159
+ {formatMessage({
160
+ id: 'Settings.application.link-upgrade',
161
+ defaultMessage: 'Upgrade your admin panel',
162
+ })}
163
+ </Link>
164
+ )}
165
+ </GridItem>
166
+ <GridItem col={6} s={12}>
97
167
  <Link
98
- href={`https://github.com/strapi/strapi/releases/tag/${latestStrapiReleaseTag}`}
168
+ href="https://strapi.io/pricing-self-hosted"
169
+ isExternal
99
170
  endIcon={<ExternalLink />}
100
171
  >
101
172
  {formatMessage({
102
- id: 'Settings.application.link-upgrade',
103
- defaultMessage: 'Upgrade your admin panel',
173
+ id: 'Settings.application.link-pricing',
174
+ defaultMessage: 'See all pricing plans',
104
175
  })}
105
176
  </Link>
106
- )}
107
- </GridItem>
108
- <GridItem col={6} s={12}>
109
- <Link href="https://strapi.io/pricing-self-hosted" endIcon={<ExternalLink />}>
177
+ </GridItem>
178
+ </Grid>
179
+
180
+ <Box paddingTop={1}>
181
+ <Typography variant="sigma" textColor="neutral600">
110
182
  {formatMessage({
111
- id: 'Settings.application.link-pricing',
112
- defaultMessage: 'See all pricing plans',
183
+ id: 'Settings.application.node-version',
184
+ defaultMessage: 'node version',
113
185
  })}
114
- </Link>
115
- </GridItem>
116
- </Grid>
117
-
118
- <Box paddingTop={1}>
119
- <Typography variant="sigma" textColor="neutral600">
120
- {formatMessage({
121
- id: 'Settings.application.node-version',
122
- defaultMessage: 'node version',
123
- })}
124
- </Typography>
125
- <Typography as="p">{appInfos.nodeVersion}</Typography>
126
- </Box>
127
- </Stack>
128
- </Box>
186
+ </Typography>
187
+ <Typography as="p">{appInfos.nodeVersion}</Typography>
188
+ </Box>
189
+ </Stack>
190
+ </Box>
191
+ {data && (
192
+ <CheckPermissions permissions={permissions}>
193
+ <Form ref={inputsRef} projectSettingsStored={data} />
194
+ </CheckPermissions>
195
+ )}
196
+ </Stack>
129
197
  </ContentLayout>
130
198
  </Main>
131
199
  </Layout>
@@ -0,0 +1,16 @@
1
+ import { axiosInstance } from '../../../../../core/utils';
2
+ import prefixAllUrls from './prefixAllUrls';
3
+
4
+ const fetchProjectSettings = async () => {
5
+ const { data } = await axiosInstance.get('/admin/project-settings');
6
+
7
+ return prefixAllUrls(data);
8
+ };
9
+
10
+ const postProjectSettings = async body => {
11
+ const { data } = await axiosInstance.post('/admin/project-settings', body);
12
+
13
+ return prefixAllUrls(data);
14
+ };
15
+
16
+ export { fetchProjectSettings, postProjectSettings };
@@ -0,0 +1,3 @@
1
+ export const DIMENSION = 750;
2
+ export const SIZE = 100;
3
+ export const ACCEPTED_FORMAT = ['image/jpeg', 'image/png', 'image/svg+xml'];
@@ -0,0 +1,17 @@
1
+ const getFormData = data => {
2
+ const formData = new FormData();
3
+
4
+ Object.entries(data).forEach(([key, value]) => {
5
+ if (value && value.rawFile instanceof File) {
6
+ formData.append(key, value.rawFile);
7
+ }
8
+
9
+ if (value && value.isReset) {
10
+ formData.append(key, null);
11
+ }
12
+ });
13
+
14
+ return formData;
15
+ };
16
+
17
+ export default getFormData;
@@ -0,0 +1,76 @@
1
+ import { DIMENSION, SIZE, ACCEPTED_FORMAT } from './constants';
2
+
3
+ const FILE_FORMAT_ERROR_MESSAGE = {
4
+ id: 'Settings.application.customization.modal.upload.error-format',
5
+ defaultMessage: 'Wrong format uploaded (accepted formats only: jpeg, jpg, png, svg).',
6
+ };
7
+
8
+ const FILE_SIZING_ERROR_MESSAGE = {
9
+ id: 'Settings.application.customization.modal.upload.error-size',
10
+ defaultMessage:
11
+ 'The file uploaded is too large (max dimension: {dimension}x{dimension}, max file size: {size}KB)',
12
+ };
13
+
14
+ const getFileDimensions = file => {
15
+ return new Promise(resolve => {
16
+ const reader = new FileReader();
17
+ reader.onload = () => {
18
+ const img = new Image();
19
+ img.onload = function() {
20
+ resolve({ width: img.width, height: img.height });
21
+ };
22
+ img.src = reader.result;
23
+ };
24
+ reader.readAsDataURL(file);
25
+ });
26
+ };
27
+
28
+ const rawFileToAsset = (rawFile, fileDimensions) => {
29
+ return {
30
+ ext: rawFile.name.split('.').pop(),
31
+ size: rawFile.size / 1000,
32
+ name: rawFile.name,
33
+ url: URL.createObjectURL(rawFile),
34
+ rawFile,
35
+ width: fileDimensions.width,
36
+ height: fileDimensions.height,
37
+ };
38
+ };
39
+
40
+ export const parseFileMetadatas = async file => {
41
+ let error;
42
+
43
+ const isFormatAuthorized = ACCEPTED_FORMAT.includes(file.type);
44
+
45
+ if (!isFormatAuthorized) {
46
+ error = new Error('File format');
47
+ error.displayMessage = FILE_FORMAT_ERROR_MESSAGE;
48
+
49
+ throw error;
50
+ }
51
+
52
+ const fileDimensions = await getFileDimensions(file);
53
+
54
+ const areDimensionsAuthorized =
55
+ fileDimensions.width <= DIMENSION && fileDimensions.height <= DIMENSION;
56
+
57
+ if (!areDimensionsAuthorized) {
58
+ error = new Error('File sizing');
59
+ error.displayMessage = FILE_SIZING_ERROR_MESSAGE;
60
+
61
+ throw error;
62
+ }
63
+
64
+ const asset = rawFileToAsset(file, fileDimensions);
65
+
66
+ const isSizeAuthorized = asset.size <= SIZE;
67
+
68
+ if (!isSizeAuthorized) {
69
+ error = new Error('File sizing');
70
+ error.displayMessage = FILE_SIZING_ERROR_MESSAGE;
71
+
72
+ throw error;
73
+ }
74
+
75
+ return asset;
76
+ };
@@ -0,0 +1,17 @@
1
+ import transform from 'lodash/transform';
2
+ import { prefixFileUrlWithBackendUrl } from '@strapi/helper-plugin';
3
+
4
+ const prefixAllUrls = data =>
5
+ transform(
6
+ data,
7
+ (result, value, key) => {
8
+ if (value && value.url) {
9
+ result[key] = { ...value, url: prefixFileUrlWithBackendUrl(value.url) };
10
+ } else {
11
+ result[key] = value;
12
+ }
13
+ },
14
+ {}
15
+ );
16
+
17
+ export default prefixAllUrls;
@@ -0,0 +1,21 @@
1
+ import axios from 'axios';
2
+
3
+ const urlToFile = async url => {
4
+ try {
5
+ const res = await axios.get(url, { responseType: 'blob', timeout: 8000 });
6
+ const loadedFile = new File([res.data], res.config.url, {
7
+ type: res.headers['content-type'],
8
+ });
9
+
10
+ return loadedFile;
11
+ } catch (err) {
12
+ err.displayMessage = {
13
+ id: 'Settings.application.customization.modal.upload.error-network',
14
+ defaultMessage: 'Network error',
15
+ };
16
+
17
+ throw err;
18
+ }
19
+ };
20
+
21
+ export default urlToFile;
@@ -6,6 +6,7 @@ import {
6
6
  useTracking,
7
7
  LoadingIndicatorPage,
8
8
  SettingsPageTitle,
9
+ Link,
9
10
  } from '@strapi/helper-plugin';
10
11
  import { Box } from '@strapi/design-system/Box';
11
12
  import { Button } from '@strapi/design-system/Button';
@@ -13,7 +14,6 @@ import { ContentLayout, HeaderLayout } from '@strapi/design-system/Layout';
13
14
  import { Main } from '@strapi/design-system/Main';
14
15
  import { Stack } from '@strapi/design-system/Stack';
15
16
  import { Formik } from 'formik';
16
- import { Link } from '@strapi/design-system/Link';
17
17
  import ArrowLeft from '@strapi/icons/ArrowLeft';
18
18
  import get from 'lodash/get';
19
19
  import { useIntl } from 'react-intl';
@@ -15,6 +15,7 @@ import {
15
15
  useNotification,
16
16
  useOverlayBlocker,
17
17
  LoadingIndicatorPage,
18
+ Link,
18
19
  } from '@strapi/helper-plugin';
19
20
  import { useQuery } from 'react-query';
20
21
  import { Formik } from 'formik';
@@ -22,7 +23,6 @@ import { Box } from '@strapi/design-system/Box';
22
23
  import { Button } from '@strapi/design-system/Button';
23
24
  import { Grid, GridItem } from '@strapi/design-system/Grid';
24
25
  import { HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
25
- import { Link } from '@strapi/design-system/Link';
26
26
  import { Typography } from '@strapi/design-system/Typography';
27
27
  import { Main } from '@strapi/design-system/Main';
28
28
  import { Stack } from '@strapi/design-system/Stack';
@@ -1,13 +1,12 @@
1
1
  import React, { useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { Form } from '@strapi/helper-plugin';
3
+ import { Form, Link } from '@strapi/helper-plugin';
4
4
  import ArrowLeft from '@strapi/icons/ArrowLeft';
5
5
  import Check from '@strapi/icons/Check';
6
6
  import Publish from '@strapi/icons/Play';
7
7
  import { ContentLayout, HeaderLayout } from '@strapi/design-system/Layout';
8
8
  import { Box } from '@strapi/design-system/Box';
9
9
  import { Button } from '@strapi/design-system/Button';
10
- import { Link } from '@strapi/design-system/Link';
11
10
  import { Stack } from '@strapi/design-system/Stack';
12
11
  import { TextInput } from '@strapi/design-system/TextInput';
13
12
  import { Grid, GridItem } from '@strapi/design-system/Grid';
@@ -17,6 +17,7 @@ import {
17
17
  ConfirmDialog,
18
18
  onRowClick,
19
19
  stopPropagation,
20
+ LinkButton,
20
21
  } from '@strapi/helper-plugin';
21
22
  import { HeaderLayout, Layout, ContentLayout, ActionLayout } from '@strapi/design-system/Layout';
22
23
  import { EmptyStateLayout } from '@strapi/design-system/EmptyStateLayout';
@@ -30,7 +31,6 @@ import { Button } from '@strapi/design-system/Button';
30
31
  import { VisuallyHidden } from '@strapi/design-system/VisuallyHidden';
31
32
  import { Switch } from '@strapi/design-system/Switch';
32
33
  import { Main } from '@strapi/design-system/Main';
33
- import { LinkButton } from '@strapi/design-system/LinkButton';
34
34
  import { useNotifyAT } from '@strapi/design-system/LiveRegions';
35
35
  import { Box } from '@strapi/design-system/Box';
36
36
  import Plus from '@strapi/icons/Plus';
@@ -1,13 +1,12 @@
1
- import appReducer from './pages/App/reducer';
2
1
  import rbacProviderReducer from './components/RBACProvider/reducer';
3
- import cmAppReducer from './content-manager/pages/App/reducer';
2
+ import appReducer from './content-manager/pages/App/reducer';
4
3
  import editViewLayoutManagerReducer from './content-manager/pages/EditViewLayoutManager/reducer';
5
4
  import listViewReducer from './content-manager/pages/ListView/reducer';
6
5
  import rbacManagerReducer from './content-manager/hooks/useSyncRbac/reducer';
7
6
  import editViewCrudReducer from './content-manager/sharedReducers/crudReducer/reducer';
8
7
 
9
8
  const contentManagerReducers = {
10
- 'content-manager_app': cmAppReducer,
9
+ 'content-manager_app': appReducer,
11
10
  'content-manager_listView': listViewReducer,
12
11
  'content-manager_rbacManager': rbacManagerReducer,
13
12
  'content-manager_editViewLayoutManager': editViewLayoutManagerReducer,
@@ -15,7 +14,6 @@ const contentManagerReducers = {
15
14
  };
16
15
 
17
16
  const reducers = {
18
- admin_app: appReducer,
19
17
  rbacProvider: rbacProviderReducer,
20
18
  ...contentManagerReducers,
21
19
  };
@@ -99,6 +99,31 @@
99
99
  "Settings.application.strapi-version": "strapi version",
100
100
  "Settings.application.strapiVersion": "strapi version",
101
101
  "Settings.application.title": "Overview",
102
+ "Settings.application.customization": "Customization",
103
+ "Settings.application.customization.carousel.title": "Logo",
104
+ "Settings.application.customization.carousel.change-action": "Change logo",
105
+ "Settings.application.customization.carousel.reset-action": "Reset logo",
106
+ "Settings.application.customization.carousel-slide.label": "Logo slide",
107
+ "Settings.application.customization.carousel-hint": "Change the admin panel logo (Max dimension: {dimension}x{dimension}, Max file size: {size}KB)",
108
+ "Settings.application.customization.modal.cancel": "Cancel",
109
+ "Settings.application.customization.modal.upload": "Upload logo",
110
+ "Settings.application.customization.modal.tab.label": "How do you want to upload your assets?",
111
+ "Settings.application.customization.modal.upload.from-computer": "From computer",
112
+ "Settings.application.customization.modal.upload.file-validation": "Max dimension: {dimension}x{dimension}, Max size: {size}KB",
113
+ "Settings.application.customization.modal.upload.error-format": "Wrong format uploaded (accepted formats only: jpeg, jpg, png, svg).",
114
+ "Settings.application.customization.modal.upload.error-size": "The file uploaded is too large (max dimension: {dimension}x{dimension}, max file size: {size}KB)",
115
+ "Settings.application.customization.modal.upload.error-network": "Network error",
116
+ "Settings.application.customization.modal.upload.cta.browse": "Browse files",
117
+ "Settings.application.customization.modal.upload.drag-drop": "Drag and Drop here or",
118
+ "Settings.application.customization.modal.upload.from-url": "From url",
119
+ "Settings.application.customization.modal.upload.from-url.input-label": "URL",
120
+ "Settings.application.customization.modal.upload.next": "Next",
121
+ "Settings.application.customization.modal.pending": "Pending logo",
122
+ "Settings.application.customization.modal.pending.choose-another": "Choose another logo",
123
+ "Settings.application.customization.modal.pending.title": "Logo ready to upload",
124
+ "Settings.application.customization.modal.pending.subtitle": "Manage the chosen logo before uploading it",
125
+ "Settings.application.customization.modal.pending.upload": "Upload logo",
126
+ "Settings.application.customization.modal.pending.card-badge": "image",
102
127
  "Settings.error": "Error",
103
128
  "Settings.global": "Global Settings",
104
129
  "Settings.permissions": "Administration panel",
@@ -207,6 +232,7 @@
207
232
  "admin.pages.MarketPlacePage.helmet": "Marketplace - Plugins",
208
233
  "admin.pages.MarketPlacePage.offline.title": "You are offline",
209
234
  "admin.pages.MarketPlacePage.offline.subtitle": "You need to be connected to the Internet to access Strapi Market.",
235
+ "admin.pages.MarketPlacePage.plugins": "Plugins",
210
236
  "admin.pages.MarketPlacePage.plugin.copy": "Copy install command",
211
237
  "admin.pages.MarketPlacePage.plugin.copy.success": "Install command ready to be pasted in your terminal",
212
238
  "admin.pages.MarketPlacePage.plugin.info": "Learn more",
@@ -215,11 +241,14 @@
215
241
  "admin.pages.MarketPlacePage.plugin.installed": "Installed",
216
242
  "admin.pages.MarketPlacePage.plugin.tooltip.madeByStrapi": "Made by Strapi",
217
243
  "admin.pages.MarketPlacePage.plugin.tooltip.verified": "Plugin verified by Strapi",
218
- "admin.pages.MarketPlacePage.search.clear": "Clear the plugin search",
244
+ "admin.pages.MarketPlacePage.providers": "Providers",
245
+ "admin.pages.MarketPlacePage.search.clear": "Clear the search",
219
246
  "admin.pages.MarketPlacePage.search.empty": "No result for \"{target}\"",
220
- "admin.pages.MarketPlacePage.search.placeholder": "Search for a plugin",
221
- "admin.pages.MarketPlacePage.submit.plugin.link": "Submit your plugin",
247
+ "admin.pages.MarketPlacePage.search.placeholder": "Search",
248
+ "admin.pages.MarketPlacePage.submit.plugin.link": "Submit plugin",
249
+ "admin.pages.MarketPlacePage.submit.provider.link": "Submit provider",
222
250
  "admin.pages.MarketPlacePage.subtitle": "Get more out of Strapi",
251
+ "admin.pages.MarketPlacePage.tab-group.label": "Plugins and Providers for Strapi",
223
252
  "admin.pages.MarketPlacePage.missingPlugin.title": "Missing a plugin?",
224
253
  "admin.pages.MarketPlacePage.missingPlugin.description": "Tell us what plugin you are looking for and we'll let our community plugin developers know in case they are in search for inspiration!",
225
254
  "anErrorOccurred": "Woops! Something went wrong. Please, try again.",
@@ -292,6 +321,7 @@
292
321
  "app.components.LeftMenu.collapse": "Collapse the navbar",
293
322
  "app.components.LeftMenu.expand": "Expand the navbar",
294
323
  "app.components.LeftMenu.logout": "Logout",
324
+ "app.components.LeftMenu.logo.alt": "Application logo",
295
325
  "app.components.LeftMenu.navbrand.title": "Strapi Dashboard",
296
326
  "app.components.LeftMenu.navbrand.workplace": "Workplace",
297
327
  "app.components.LeftMenuFooter.help": "Help",