@strapi/admin 4.2.0-beta.1 → 4.2.0-beta.4

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 (166) hide show
  1. package/admin/src/assets/images/homepage-logo.png +0 -0
  2. package/admin/src/components/AutoReloadOverlayBlockerProvider/Blocker.js +2 -6
  3. package/admin/src/components/ConfigurationsProvider/index.js +51 -0
  4. package/admin/src/components/ConfigurationsProvider/reducer.js +28 -0
  5. package/admin/src/components/GuidedTour/Homepage/index.js +1 -2
  6. package/admin/src/components/GuidedTour/Modal/components/Stepper.js +1 -2
  7. package/admin/src/components/LeftMenu/index.js +19 -7
  8. package/admin/src/components/Notifications/Notification/index.js +2 -2
  9. package/admin/src/components/Providers/index.js +8 -4
  10. package/admin/src/components/UnauthenticatedLogo/index.js +4 -2
  11. package/admin/src/components/UpgradePlanModal/index.js +6 -2
  12. package/admin/src/content-manager/components/DynamicZone/components/ComponentPicker/Category/ComponentCard/index.js +1 -1
  13. package/admin/src/content-manager/components/SelectMany/ListItem.js +1 -2
  14. package/admin/src/content-manager/components/SelectWrapper/index.js +8 -7
  15. package/admin/src/content-manager/components/SelectWrapper/utils/getSelectStyles.js +1 -1
  16. package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +2 -2
  17. package/admin/src/content-manager/components/Wysiwyg/Editor.js +2 -0
  18. package/admin/src/content-manager/pages/App/LeftMenu/index.js +8 -7
  19. package/admin/src/content-manager/pages/EditSettingsView/components/ComponentFieldList.js +1 -1
  20. package/admin/src/content-manager/pages/EditSettingsView/components/LinkToCTB.js +1 -2
  21. package/admin/src/content-manager/pages/EditSettingsView/index.js +1 -2
  22. package/admin/src/content-manager/pages/EditView/Header/index.js +3 -3
  23. package/admin/src/content-manager/pages/EditView/index.js +1 -4
  24. package/admin/src/content-manager/pages/ListSettingsView/index.js +1 -2
  25. package/admin/src/content-manager/pages/ListView/index.js +1 -1
  26. package/admin/src/content-manager/pages/NoContentType/index.js +1 -2
  27. package/admin/src/pages/App/index.js +7 -2
  28. package/admin/src/pages/AuthPage/components/ForgotPassword/index.js +1 -2
  29. package/admin/src/pages/AuthPage/components/ForgotPasswordSuccess/index.js +1 -1
  30. package/admin/src/pages/AuthPage/components/Login/BaseLogin.js +1 -2
  31. package/admin/src/pages/AuthPage/components/Oops/index.js +1 -2
  32. package/admin/src/pages/AuthPage/components/Register/index.js +12 -12
  33. package/admin/src/pages/AuthPage/components/ResetPassword/index.js +3 -4
  34. package/admin/src/pages/HomePage/ContentBlocks.js +15 -2
  35. package/admin/src/pages/HomePage/HomeHeader.js +2 -2
  36. package/admin/src/pages/HomePage/SocialLinks.js +4 -3
  37. package/admin/src/pages/InternalErrorPage/index.js +1 -2
  38. package/admin/src/pages/MarketplacePage/components/PageHeader/index.js +2 -1
  39. package/admin/src/pages/MarketplacePage/components/PluginCard/index.js +4 -3
  40. package/admin/src/pages/NotFoundPage/index.js +1 -2
  41. package/admin/src/pages/SettingsPage/components/SettingsNav/index.js +5 -4
  42. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +1 -1
  43. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js +1 -1
  44. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +1 -1
  45. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/index.js +85 -0
  46. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/init.js +13 -0
  47. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/reducer.js +43 -0
  48. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/index.js +118 -0
  49. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/reducer.js +28 -0
  50. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/stepper.js +25 -0
  51. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/AddLogoDialog.js +67 -0
  52. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/FromComputerForm.js +176 -0
  53. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/FromUrlForm.js +82 -0
  54. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/ImageCardAsset.js +51 -0
  55. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/PendingLogoDialog.js +97 -0
  56. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/index.js +85 -0
  57. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/reducer.js +28 -0
  58. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/index.js +155 -87
  59. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/api.js +16 -0
  60. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/constants.js +3 -0
  61. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/getFormData.js +17 -0
  62. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/parseFileMetadatas.js +76 -0
  63. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/prefixAllUrls.js +17 -0
  64. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/urlToFile.js +21 -0
  65. package/admin/src/pages/SettingsPage/pages/Roles/EditPage/index.js +1 -1
  66. package/admin/src/pages/SettingsPage/pages/Users/EditPage/index.js +1 -1
  67. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/index.js +1 -2
  68. package/admin/src/pages/SettingsPage/pages/Webhooks/ListView/index.js +1 -1
  69. package/admin/src/translations/ca.json +699 -0
  70. package/admin/src/translations/en.json +26 -0
  71. package/admin/src/translations/languageNativeNames.js +1 -0
  72. package/admin/src/translations/ru.json +34 -0
  73. package/build/1541.6c1c96f9.chunk.js +307 -0
  74. package/build/1856.521a99fd.chunk.js +172 -0
  75. package/build/2077.51485bfb.chunk.js +194 -0
  76. package/build/2912.79c2b3c8.chunk.js +253 -0
  77. package/build/3214.9196aeff.chunk.js +235 -0
  78. package/build/3865.21cec9de.chunk.js +310 -0
  79. package/build/4073.e144a91a.chunk.js +1 -0
  80. package/build/4715.77e04177.chunk.js +385 -0
  81. package/build/{272.d442e5ca.chunk.js → 472.0350a5bd.chunk.js} +91 -102
  82. package/build/4982.f53b78a4.chunk.js +308 -0
  83. package/build/6229.a5cca9f2.chunk.js +194 -0
  84. package/build/7351.b95e65ae.chunk.js +428 -0
  85. package/build/7418.6db737ce.chunk.js +112 -0
  86. package/build/7841.f0e7d629.chunk.js +253 -0
  87. package/build/8826.58e236d4.chunk.js +1057 -0
  88. package/build/9066.118ecccd.chunk.js +101 -0
  89. package/build/{9298.dab64a1b.chunk.js → 9298.aff28744.chunk.js} +80 -91
  90. package/build/9420.cb0b75e8.chunk.js +508 -0
  91. package/build/{9988.9b6e1d79.chunk.js → 9988.f84412d9.chunk.js} +15 -14
  92. package/build/Admin-authenticatedApp.162a5805.chunk.js +80 -0
  93. package/build/Admin_homePage.0ac648e8.chunk.js +71 -0
  94. package/build/Admin_marketplace.0bb91ec8.chunk.js +11 -0
  95. package/build/Admin_settingsPage.23e873f0.chunk.js +178 -0
  96. package/build/admin-edit-roles-page.fb374555.chunk.js +1 -0
  97. package/build/admin-edit-users.a360deaf.chunk.js +10 -0
  98. package/build/api-tokens-create-page.698f132d.chunk.js +1 -0
  99. package/build/api-tokens-edit-page.afece2fe.chunk.js +1 -0
  100. package/build/api-tokens-list-page.46d96dee.chunk.js +15 -0
  101. package/build/ca-json.0097e443.chunk.js +1 -0
  102. package/build/content-manager.7cd28f84.chunk.js +1204 -0
  103. package/build/content-type-builder.7456cabe.chunk.js +141 -0
  104. package/build/{email-settings-page.d807edfd.chunk.js → email-settings-page.f67d13b2.chunk.js} +5 -5
  105. package/build/en-json.40ee00aa.chunk.js +1 -0
  106. package/build/fb376b132d18bf4522ca.png +0 -0
  107. package/build/{i18n-settings-page.c8f3b78b.chunk.js → i18n-settings-page.6b67cb75.chunk.js} +5 -5
  108. package/build/index.html +1 -1
  109. package/build/main.b632a0d6.js +11625 -0
  110. package/build/ru-json.28147733.chunk.js +1 -0
  111. package/build/runtime~main.38d418e9.js +2 -0
  112. package/build/{upload-settings.17202e3b.chunk.js → upload-settings.3db55de0.chunk.js} +5 -5
  113. package/build/upload-translation-ca-json.79159984.chunk.js +1 -0
  114. package/build/{upload.d647d59d.chunk.js → upload.070c189b.chunk.js} +5 -5
  115. package/build/{users-advanced-settings-page.22690469.chunk.js → users-advanced-settings-page.a23cda17.chunk.js} +5 -5
  116. package/build/users-roles-settings-page.988ebc3b.chunk.js +30 -0
  117. package/build/{webhook-edit-page.043fe03f.chunk.js → webhook-edit-page.a7ae6e3b.chunk.js} +3 -3
  118. package/build/webhook-list-page.83297d98.chunk.js +133 -0
  119. package/ee/admin/pages/AuthPage/components/Providers/index.js +1 -1
  120. package/ee/admin/pages/SettingsPage/pages/Roles/CreatePage/index.js +1 -1
  121. package/ee/server/controllers/user.js +4 -0
  122. package/package.json +9 -9
  123. package/server/config/admin-actions.js +14 -0
  124. package/server/controllers/admin.js +33 -1
  125. package/server/controllers/user.js +4 -0
  126. package/server/routes/admin.js +28 -0
  127. package/server/services/index.js +1 -0
  128. package/server/services/permission/permissions-manager/sanitize.js +22 -0
  129. package/server/services/project-settings.js +173 -0
  130. package/server/services/user.js +1 -1
  131. package/server/utils/index.d.ts +2 -0
  132. package/server/validation/project-settings.js +39 -0
  133. package/utils/create-cache-dir.js +2 -5
  134. package/webpack.config.js +2 -2
  135. package/admin/src/content-manager/components/DynamicComponentCard/index.js +0 -43
  136. package/build/1856.e2bce2e8.chunk.js +0 -171
  137. package/build/2481.5fe150c7.chunk.js +0 -184
  138. package/build/2912.5a7b0406.chunk.js +0 -252
  139. package/build/2a9e9ef5c4c775bb7c7b.png +0 -0
  140. package/build/306.28d21ab8.chunk.js +0 -896
  141. package/build/4073.4765687b.chunk.js +0 -1
  142. package/build/4715.7f616cf6.chunk.js +0 -387
  143. package/build/497.2ba35e90.chunk.js +0 -284
  144. package/build/4982.91235074.chunk.js +0 -310
  145. package/build/6229.f558fd19.chunk.js +0 -194
  146. package/build/6404.25d0f0d8.chunk.js +0 -508
  147. package/build/7841.0d73dde1.chunk.js +0 -252
  148. package/build/7863.996e70df.chunk.js +0 -112
  149. package/build/9853.6cc1043a.chunk.js +0 -354
  150. package/build/Admin-authenticatedApp.d26b3032.chunk.js +0 -80
  151. package/build/Admin_homePage.fc4a8408.chunk.js +0 -71
  152. package/build/Admin_marketplace.c406a140.chunk.js +0 -11
  153. package/build/Admin_settingsPage.c40fdef1.chunk.js +0 -170
  154. package/build/admin-edit-roles-page.c69fe8ab.chunk.js +0 -1
  155. package/build/admin-edit-users.be232f6b.chunk.js +0 -10
  156. package/build/api-tokens-create-page.9774f0fe.chunk.js +0 -1
  157. package/build/api-tokens-edit-page.8f03c9a1.chunk.js +0 -1
  158. package/build/api-tokens-list-page.126fbca6.chunk.js +0 -15
  159. package/build/content-manager.ca66b566.chunk.js +0 -1204
  160. package/build/content-type-builder.d12fd5cd.chunk.js +0 -141
  161. package/build/en-json.3e1a222e.chunk.js +0 -1
  162. package/build/main.36da7eeb.js +0 -7918
  163. package/build/ru-json.4560906c.chunk.js +0 -1
  164. package/build/runtime~main.251e9cca.js +0 -2
  165. package/build/users-roles-settings-page.487f3346.chunk.js +0 -30
  166. package/build/webhook-list-page.2d2d71a1.chunk.js +0 -132
@@ -1,16 +1,15 @@
1
1
  import React, { useState } from 'react';
2
+ import { Form, Link } from '@strapi/helper-plugin';
2
3
  import EyeStriked from '@strapi/icons/EyeStriked';
3
4
  import Eye from '@strapi/icons/Eye';
4
5
  import { Box } from '@strapi/design-system/Box';
5
6
  import { Stack } from '@strapi/design-system/Stack';
6
7
  import { Main } from '@strapi/design-system/Main';
7
8
  import { Flex } from '@strapi/design-system/Flex';
8
- import { Link } from '@strapi/design-system/Link';
9
9
  import { Button } from '@strapi/design-system/Button';
10
10
  import { TextInput } from '@strapi/design-system/TextInput';
11
11
  import { Checkbox } from '@strapi/design-system/Checkbox';
12
12
  import { Typography } from '@strapi/design-system/Typography';
13
- import { Form } from '@strapi/helper-plugin';
14
13
  import PropTypes from 'prop-types';
15
14
  import { useIntl } from 'react-intl';
16
15
  import styled from 'styled-components';
@@ -1,10 +1,9 @@
1
1
  import React from 'react';
2
2
  import { useIntl } from 'react-intl';
3
- import { useQuery } from '@strapi/helper-plugin';
3
+ import { useQuery, Link } from '@strapi/helper-plugin';
4
4
  import { Box } from '@strapi/design-system/Box';
5
5
  import { Main } from '@strapi/design-system/Main';
6
6
  import { Flex } from '@strapi/design-system/Flex';
7
- import { Link } from '@strapi/design-system/Link';
8
7
  import { Typography } from '@strapi/design-system/Typography';
9
8
  import UnauthenticatedLayout, {
10
9
  Column,
@@ -3,11 +3,22 @@ import { useIntl } from 'react-intl';
3
3
  import styled from 'styled-components';
4
4
  import get from 'lodash/get';
5
5
  import omit from 'lodash/omit';
6
+ import { useHistory } from 'react-router-dom';
7
+ import PropTypes from 'prop-types';
8
+ import { Formik } from 'formik';
9
+ import axios from 'axios';
10
+ import {
11
+ Form,
12
+ useQuery,
13
+ useNotification,
14
+ useTracking,
15
+ getYupInnerErrors,
16
+ Link,
17
+ } from '@strapi/helper-plugin';
6
18
  import { Box } from '@strapi/design-system/Box';
7
19
  import { Stack } from '@strapi/design-system/Stack';
8
20
  import { Main } from '@strapi/design-system/Main';
9
21
  import { Flex } from '@strapi/design-system/Flex';
10
- import { Link } from '@strapi/design-system/Link';
11
22
  import { Button } from '@strapi/design-system/Button';
12
23
  import { TextInput } from '@strapi/design-system/TextInput';
13
24
  import { Checkbox } from '@strapi/design-system/Checkbox';
@@ -15,17 +26,6 @@ import { Grid, GridItem } from '@strapi/design-system/Grid';
15
26
  import { Typography } from '@strapi/design-system/Typography';
16
27
  import EyeStriked from '@strapi/icons/EyeStriked';
17
28
  import Eye from '@strapi/icons/Eye';
18
- import {
19
- Form,
20
- useQuery,
21
- useNotification,
22
- useTracking,
23
- getYupInnerErrors,
24
- } from '@strapi/helper-plugin';
25
- import { useHistory } from 'react-router-dom';
26
- import PropTypes from 'prop-types';
27
- import { Formik } from 'formik';
28
- import axios from 'axios';
29
29
  import UnauthenticatedLayout, {
30
30
  Column,
31
31
  LayoutContent,
@@ -1,19 +1,18 @@
1
1
  import React, { useState } from 'react';
2
2
  import { useIntl } from 'react-intl';
3
3
  import PropTypes from 'prop-types';
4
- import { Form } from '@strapi/helper-plugin';
4
+ import styled from 'styled-components';
5
+ import { Formik } from 'formik';
6
+ import { Form, Link } from '@strapi/helper-plugin';
5
7
  import { Box } from '@strapi/design-system/Box';
6
8
  import { Stack } from '@strapi/design-system/Stack';
7
9
  import { Main } from '@strapi/design-system/Main';
8
10
  import { Flex } from '@strapi/design-system/Flex';
9
- import { Link } from '@strapi/design-system/Link';
10
11
  import { Button } from '@strapi/design-system/Button';
11
12
  import { TextInput } from '@strapi/design-system/TextInput';
12
13
  import { Typography } from '@strapi/design-system/Typography';
13
14
  import EyeStriked from '@strapi/icons/EyeStriked';
14
15
  import Eye from '@strapi/icons/Eye';
15
- import styled from 'styled-components';
16
- import { Formik } from 'formik';
17
16
  import UnauthenticatedLayout, {
18
17
  Column,
19
18
  LayoutContent,
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  import styled from 'styled-components';
3
3
  import { useIntl } from 'react-intl';
4
+ import { ContentBox, useTracking } from '@strapi/helper-plugin';
4
5
  import { Stack } from '@strapi/design-system/Stack';
5
6
  import InformationSquare from '@strapi/icons/InformationSquare';
6
7
  import CodeSquare from '@strapi/icons/CodeSquare';
7
8
  import PlaySquare from '@strapi/icons/PlaySquare';
8
9
  import FeatherSquare from '@strapi/icons/FeatherSquare';
9
- import { ContentBox } from '@strapi/helper-plugin';
10
10
 
11
11
  const BlockLink = styled.a`
12
12
  text-decoration: none;
@@ -14,6 +14,11 @@ const BlockLink = styled.a`
14
14
 
15
15
  const ContentBlocks = () => {
16
16
  const { formatMessage } = useIntl();
17
+ const { trackUsage } = useTracking();
18
+
19
+ const handleClick = eventName => {
20
+ trackUsage(eventName);
21
+ };
17
22
 
18
23
  return (
19
24
  <Stack spacing={5}>
@@ -21,6 +26,7 @@ const ContentBlocks = () => {
21
26
  href="https://strapi.io/resource-center"
22
27
  target="_blank"
23
28
  rel="noopener noreferrer nofollow"
29
+ onClick={() => handleClick('didClickonReadTheDocumentationSection')}
24
30
  >
25
31
  <ContentBox
26
32
  title={formatMessage({
@@ -39,6 +45,7 @@ const ContentBlocks = () => {
39
45
  href="https://strapi.io/starters"
40
46
  target="_blank"
41
47
  rel="noopener noreferrer nofollow"
48
+ onClick={() => handleClick('didClickonCodeExampleSection')}
42
49
  >
43
50
  <ContentBox
44
51
  title={formatMessage({
@@ -57,6 +64,7 @@ const ContentBlocks = () => {
57
64
  href="https://strapi.io/blog/categories/tutorials"
58
65
  target="_blank"
59
66
  rel="noopener noreferrer nofollow"
67
+ onClick={() => handleClick('didClickonTutorialSection')}
60
68
  >
61
69
  <ContentBox
62
70
  title={formatMessage({
@@ -71,7 +79,12 @@ const ContentBlocks = () => {
71
79
  iconBackground="secondary100"
72
80
  />
73
81
  </BlockLink>
74
- <BlockLink href="https://strapi.io/blog" target="_blank" rel="noopener noreferrer nofollow">
82
+ <BlockLink
83
+ href="https://strapi.io/blog"
84
+ target="_blank"
85
+ rel="noopener noreferrer nofollow"
86
+ onClick={() => handleClick('didClickonBlogSection')}
87
+ >
75
88
  <ContentBox
76
89
  title={formatMessage({
77
90
  id: 'app.components.BlockLink.blog',
@@ -3,7 +3,7 @@ import styled from 'styled-components';
3
3
  import PropTypes from 'prop-types';
4
4
  import { useIntl } from 'react-intl';
5
5
  import { Typography } from '@strapi/design-system/Typography';
6
- import { Link } from '@strapi/design-system/Link';
6
+ import { Link } from '@strapi/design-system/v2/Link';
7
7
  import { Stack } from '@strapi/design-system/Stack';
8
8
  import { Box } from '@strapi/design-system/Box';
9
9
  import { Button } from '@strapi/design-system/Button';
@@ -49,7 +49,7 @@ const HomeHeader = ({ hasCreatedContentType, onCreateCT }) => {
49
49
  })}
50
50
  </WordWrap>
51
51
  {hasCreatedContentType ? (
52
- <Link href="https://strapi.io/blog">
52
+ <Link isExternal href="https://strapi.io/blog">
53
53
  {formatMessage({
54
54
  id: 'app.components.HomePage.button.blog',
55
55
  defaultMessage: 'See more on the blog',
@@ -10,8 +10,8 @@ import { Typography } from '@strapi/design-system/Typography';
10
10
  import { Box } from '@strapi/design-system/Box';
11
11
  import { Stack } from '@strapi/design-system/Stack';
12
12
  import { Grid, GridItem } from '@strapi/design-system/Grid';
13
- import { LinkButton } from '@strapi/design-system/LinkButton';
14
- import { Link } from '@strapi/design-system/Link';
13
+ import { LinkButton } from '@strapi/design-system/v2/LinkButton';
14
+ import { Link } from '@strapi/design-system/v2/Link';
15
15
  import ExternalLink from '@strapi/icons/ExternalLink';
16
16
  import Github from '@strapi/icons/Github';
17
17
  import Discord from '@strapi/icons/Discord';
@@ -167,7 +167,7 @@ const SocialLinks = () => {
167
167
  })}
168
168
  </Typography>
169
169
  </Stack>
170
- <Link href="https://feedback.strapi.io/" endIcon={<ExternalLink />}>
170
+ <Link href="https://feedback.strapi.io/" isExternal endIcon={<ExternalLink />}>
171
171
  {formatMessage({
172
172
  id: 'app.components.HomePage.roadmap',
173
173
  defaultMessage: 'See our road map',
@@ -184,6 +184,7 @@ const SocialLinks = () => {
184
184
  startIcon={socialLink.icon}
185
185
  variant="tertiary"
186
186
  href={socialLink.link}
187
+ isExternal
187
188
  >
188
189
  {socialLink.name}
189
190
  </LinkCustom>
@@ -5,9 +5,8 @@
5
5
  *
6
6
  */
7
7
  import React from 'react';
8
- import { useFocusWhenNavigate } from '@strapi/helper-plugin';
8
+ import { useFocusWhenNavigate, LinkButton } from '@strapi/helper-plugin';
9
9
  import { Main } from '@strapi/design-system/Main';
10
- import { LinkButton } from '@strapi/design-system/LinkButton';
11
10
  import { ContentLayout, HeaderLayout } from '@strapi/design-system/Layout';
12
11
  import { EmptyStateLayout } from '@strapi/design-system/EmptyStateLayout';
13
12
  import EmptyPictures from '@strapi/icons/EmptyPictures';
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useIntl } from 'react-intl';
4
4
  import { HeaderLayout } from '@strapi/design-system/Layout';
5
- import { LinkButton } from '@strapi/design-system/LinkButton';
5
+ import { LinkButton } from '@strapi/design-system/v2/LinkButton';
6
6
  import Upload from '@strapi/icons/Upload';
7
7
  import { useTracking } from '@strapi/helper-plugin';
8
8
 
@@ -27,6 +27,7 @@ const PageHeader = ({ isOnline }) => {
27
27
  variant="tertiary"
28
28
  href="https://market.strapi.io/submit-plugin"
29
29
  onClick={() => trackUsage('didSubmitPlugin')}
30
+ isExternal
30
31
  >
31
32
  {formatMessage({
32
33
  id: 'admin.pages.MarketPlacePage.submit.plugin.link',
@@ -5,7 +5,7 @@ import styled from 'styled-components';
5
5
  import { Box } from '@strapi/design-system/Box';
6
6
  import { Stack } from '@strapi/design-system/Stack';
7
7
  import { Typography } from '@strapi/design-system/Typography';
8
- import { LinkButton } from '@strapi/design-system/LinkButton';
8
+ import { LinkButton } from '@strapi/design-system/v2/LinkButton';
9
9
  import { Flex } from '@strapi/design-system/Flex';
10
10
  import { Icon } from '@strapi/design-system/Icon';
11
11
  import { Tooltip } from '@strapi/design-system/Tooltip';
@@ -46,9 +46,9 @@ const PluginCard = ({ plugin, installedPluginNames, useYarn, isInDevelopmentMode
46
46
  direction="column"
47
47
  justifyContent="space-between"
48
48
  paddingTop={4}
49
- paddingRight={6}
49
+ paddingRight={4}
50
50
  paddingBottom={4}
51
- paddingLeft={6}
51
+ paddingLeft={4}
52
52
  hasRadius
53
53
  background="neutral0"
54
54
  shadow="tableShadow"
@@ -108,6 +108,7 @@ const PluginCard = ({ plugin, installedPluginNames, useYarn, isInDevelopmentMode
108
108
  <LinkButton
109
109
  size="S"
110
110
  href={`https://market.strapi.io/plugins/${attributes.slug}`}
111
+ isExternal
111
112
  endIcon={<ExternalLink />}
112
113
  aria-label={formatMessage(
113
114
  {
@@ -5,9 +5,8 @@
5
5
  *
6
6
  */
7
7
  import React from 'react';
8
- import { useFocusWhenNavigate } from '@strapi/helper-plugin';
8
+ import { useFocusWhenNavigate, LinkButton } from '@strapi/helper-plugin';
9
9
  import { Main } from '@strapi/design-system/Main';
10
- import { LinkButton } from '@strapi/design-system/LinkButton';
11
10
  import { ContentLayout, HeaderLayout } from '@strapi/design-system/Layout';
12
11
  import { EmptyStateLayout } from '@strapi/design-system/EmptyStateLayout';
13
12
  import EmptyPictures from '@strapi/icons/EmptyPictures';
@@ -1,13 +1,14 @@
1
1
  import React from 'react';
2
+ import { NavLink } from 'react-router-dom';
3
+ import { useIntl } from 'react-intl';
4
+ import PropTypes from 'prop-types';
2
5
  import {
3
6
  SubNav,
4
7
  SubNavHeader,
5
8
  SubNavSection,
6
9
  SubNavSections,
7
10
  SubNavLink,
8
- } from '@strapi/design-system/SubNav';
9
- import { useIntl } from 'react-intl';
10
- import PropTypes from 'prop-types';
11
+ } from '@strapi/design-system/v2/SubNav';
11
12
  import { getSectionsToDisplay } from '../../utils';
12
13
 
13
14
  const SettingsNav = ({ menu }) => {
@@ -41,7 +42,7 @@ const SettingsNav = ({ menu }) => {
41
42
  {sections.map(section => (
42
43
  <SubNavSection key={section.id} label={formatMessage(section.intlLabel)}>
43
44
  {section.links.map(link => (
44
- <SubNavLink withBullet={link.hasNotification} to={link.to} key={link.id}>
45
+ <SubNavLink as={NavLink} withBullet={link.hasNotification} to={link.to} key={link.id}>
45
46
  {formatMessage(link.intlLabel)}
46
47
  </SubNavLink>
47
48
  ))}
@@ -8,13 +8,13 @@ import {
8
8
  useNotification,
9
9
  useTracking,
10
10
  useGuidedTour,
11
+ Link,
11
12
  } from '@strapi/helper-plugin';
12
13
  import { HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
13
14
  import { Main } from '@strapi/design-system/Main';
14
15
  import { Button } from '@strapi/design-system/Button';
15
16
  import Check from '@strapi/icons/Check';
16
17
  import ArrowLeft from '@strapi/icons/ArrowLeft';
17
- import { Link } from '@strapi/design-system/Link';
18
18
  import { Formik } from 'formik';
19
19
  import { Stack } from '@strapi/design-system/Stack';
20
20
  import { Box } from '@strapi/design-system/Box';
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import Pencil from '@strapi/icons/Pencil';
3
3
  import { useIntl } from 'react-intl';
4
4
  import PropTypes from 'prop-types';
5
- import { Link } from '@strapi/design-system/Link';
5
+ import { Link } from '@strapi/helper-plugin';
6
6
  import { useHistory } from 'react-router-dom';
7
7
  import styled from 'styled-components';
8
8
 
@@ -10,11 +10,11 @@ import {
10
10
  DynamicTable,
11
11
  useTracking,
12
12
  useGuidedTour,
13
+ LinkButton,
13
14
  } from '@strapi/helper-plugin';
14
15
  import { HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
15
16
  import { Main } from '@strapi/design-system/Main';
16
17
  import { Button } from '@strapi/design-system/Button';
17
- import { LinkButton } from '@strapi/design-system/LinkButton';
18
18
  import Plus from '@strapi/icons/Plus';
19
19
  import { useQuery, useMutation, useQueryClient } from 'react-query';
20
20
  import { useHistory } from 'react-router-dom';
@@ -0,0 +1,85 @@
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 LogoInput from '../LogoInput';
9
+ import { useConfigurations } from '../../../../../../hooks';
10
+ import reducer, { initialState } from './reducer';
11
+ import init from './init';
12
+
13
+ const Form = forwardRef(({ projectSettingsStored }, ref) => {
14
+ const { formatMessage } = useIntl();
15
+ const { trackUsage } = useTracking();
16
+ const {
17
+ logos: { menu },
18
+ } = useConfigurations();
19
+ const [{ menuLogo }, dispatch] = useReducer(reducer, initialState, () =>
20
+ init(initialState, projectSettingsStored)
21
+ );
22
+
23
+ const handleChangeMenuLogo = asset => {
24
+ dispatch({
25
+ type: 'SET_CUSTOM_MENU_LOGO',
26
+ value: asset,
27
+ });
28
+ };
29
+
30
+ const handleResetMenuLogo = () => {
31
+ trackUsage('didClickResetLogo');
32
+
33
+ dispatch({
34
+ type: 'RESET_CUSTOM_MENU_LOGO',
35
+ });
36
+ };
37
+
38
+ useImperativeHandle(ref, () => ({
39
+ getValues: () => ({ menuLogo: menuLogo.submit }),
40
+ }));
41
+
42
+ return (
43
+ <Box
44
+ hasRadius
45
+ background="neutral0"
46
+ shadow="tableShadow"
47
+ paddingTop={6}
48
+ paddingBottom={6}
49
+ paddingRight={7}
50
+ paddingLeft={7}
51
+ >
52
+ <Typography variant="delta" as="h3">
53
+ {formatMessage({
54
+ id: 'Settings.application.customization',
55
+ defaultMessage: 'Customization',
56
+ })}
57
+ </Typography>
58
+ <Grid paddingTop={4}>
59
+ <GridItem col={6} s={12}>
60
+ <LogoInput
61
+ onChangeLogo={handleChangeMenuLogo}
62
+ customLogo={menuLogo.display}
63
+ defaultLogo={menu.default}
64
+ onResetMenuLogo={handleResetMenuLogo}
65
+ />
66
+ </GridItem>
67
+ </Grid>
68
+ </Box>
69
+ );
70
+ });
71
+
72
+ Form.defaultProps = {
73
+ projectSettingsStored: null,
74
+ };
75
+
76
+ Form.propTypes = {
77
+ projectSettingsStored: PropTypes.shape({
78
+ menuLogo: PropTypes.shape({
79
+ url: PropTypes.string,
80
+ name: PropTypes.string,
81
+ }),
82
+ }),
83
+ };
84
+
85
+ export default Form;
@@ -0,0 +1,13 @@
1
+ import merge from 'lodash/merge';
2
+
3
+ const init = (initialState, projectSettingsStored) => {
4
+ const copyInitialState = merge(initialState, {
5
+ menuLogo: {
6
+ display: projectSettingsStored.menuLogo,
7
+ },
8
+ });
9
+
10
+ return copyInitialState;
11
+ };
12
+
13
+ export default init;
@@ -0,0 +1,43 @@
1
+ /* eslint-disable consistent-return */
2
+ /*
3
+ *
4
+ * ApplicationInfosPage Form reducer
5
+ *
6
+ */
7
+
8
+ import produce from 'immer';
9
+
10
+ const initialState = {
11
+ menuLogo: {
12
+ display: null,
13
+ submit: {
14
+ rawFile: null,
15
+ isReset: false,
16
+ },
17
+ },
18
+ };
19
+
20
+ const reducer = (state = initialState, action) =>
21
+ produce(state, draftState => {
22
+ switch (action.type) {
23
+ case 'SET_CUSTOM_MENU_LOGO': {
24
+ draftState.menuLogo.display = action.value;
25
+ draftState.menuLogo.submit.rawFile = action.value.rawFile;
26
+ break;
27
+ }
28
+ case 'RESET_CUSTOM_MENU_LOGO': {
29
+ draftState.menuLogo.display = null;
30
+ draftState.menuLogo.submit = {
31
+ rawFile: null,
32
+ isReset: true,
33
+ };
34
+ break;
35
+ }
36
+ default: {
37
+ return draftState;
38
+ }
39
+ }
40
+ });
41
+
42
+ export default reducer;
43
+ export { initialState };
@@ -0,0 +1,118 @@
1
+ import React, { useReducer } from 'react';
2
+ import { useIntl } from 'react-intl';
3
+ import PropTypes from 'prop-types';
4
+ import { CarouselInput, CarouselSlide, CarouselActions } from '@strapi/design-system/CarouselInput';
5
+ import { IconButton } from '@strapi/design-system/IconButton';
6
+ import { Box } from '@strapi/design-system/Box';
7
+ import Plus from '@strapi/icons/Plus';
8
+ import Refresh from '@strapi/icons/Refresh';
9
+ import reducer, { initialState } from './reducer';
10
+ import LogoModalStepper from '../LogoModalStepper';
11
+ import { SIZE, DIMENSION } from '../../utils/constants';
12
+ import stepper from './stepper';
13
+
14
+ const LogoInput = ({ customLogo, defaultLogo, onChangeLogo, onResetMenuLogo }) => {
15
+ const [{ currentStep }, dispatch] = useReducer(reducer, initialState);
16
+ const { Component, next, prev, modalTitle } = stepper[currentStep] || {};
17
+ const { formatMessage } = useIntl();
18
+
19
+ const goTo = to => {
20
+ dispatch({
21
+ type: 'GO_TO',
22
+ to,
23
+ });
24
+ };
25
+
26
+ return (
27
+ <>
28
+ <CarouselInput
29
+ label={formatMessage({
30
+ id: 'Settings.application.customization.carousel.title',
31
+ defaultMessage: 'Logo',
32
+ })}
33
+ 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
+ )}
42
+ // Carousel is used here for a single media,
43
+ // we don't need previous and next labels but these props are required
44
+ previousLabel=""
45
+ nextLabel=""
46
+ onNext={() => {}}
47
+ onPrevious={() => {}}
48
+ secondaryLabel={customLogo?.name || 'logo.png'}
49
+ actions={
50
+ <CarouselActions>
51
+ <IconButton
52
+ onClick={() => goTo(customLogo ? 'pending' : 'upload')}
53
+ label={formatMessage({
54
+ id: 'Settings.application.customization.carousel.change-action',
55
+ defaultMessage: 'Change logo',
56
+ })}
57
+ icon={<Plus />}
58
+ />
59
+ {customLogo && (
60
+ <IconButton
61
+ onClick={onResetMenuLogo}
62
+ label={formatMessage({
63
+ id: 'Settings.application.customization.carousel.reset-action',
64
+ defaultMessage: 'Reset logo',
65
+ })}
66
+ icon={<Refresh />}
67
+ />
68
+ )}
69
+ </CarouselActions>
70
+ }
71
+ >
72
+ <CarouselSlide
73
+ label={formatMessage({
74
+ id: 'Settings.application.customization.carousel-slide.label',
75
+ defaultMessage: 'Logo slide',
76
+ })}
77
+ >
78
+ <Box
79
+ maxHeight="40%"
80
+ maxWidth="40%"
81
+ as="img"
82
+ src={customLogo?.url || defaultLogo}
83
+ alt={formatMessage({
84
+ id: 'Settings.application.customization.carousel.title',
85
+ defaultMessage: 'Logo',
86
+ })}
87
+ />
88
+ </CarouselSlide>
89
+ </CarouselInput>
90
+ <LogoModalStepper
91
+ Component={Component}
92
+ currentStep={currentStep}
93
+ onChangeLogo={onChangeLogo}
94
+ customLogo={customLogo}
95
+ goTo={goTo}
96
+ next={next}
97
+ prev={prev}
98
+ modalTitle={modalTitle}
99
+ />
100
+ </>
101
+ );
102
+ };
103
+
104
+ LogoInput.defaultProps = {
105
+ customLogo: null,
106
+ };
107
+
108
+ LogoInput.propTypes = {
109
+ customLogo: PropTypes.shape({
110
+ url: PropTypes.string,
111
+ name: PropTypes.string,
112
+ }),
113
+ defaultLogo: PropTypes.string.isRequired,
114
+ onChangeLogo: PropTypes.func.isRequired,
115
+ onResetMenuLogo: PropTypes.func.isRequired,
116
+ };
117
+
118
+ export default LogoInput;
@@ -0,0 +1,28 @@
1
+ /* eslint-disable consistent-return */
2
+ /*
3
+ *
4
+ * LogoInput reducer
5
+ *
6
+ */
7
+
8
+ import produce from 'immer';
9
+
10
+ const initialState = {
11
+ currentStep: undefined,
12
+ };
13
+
14
+ const reducer = (state = initialState, action) =>
15
+ produce(state, draftState => {
16
+ switch (action.type) {
17
+ case 'GO_TO': {
18
+ draftState.currentStep = action.to;
19
+ break;
20
+ }
21
+ default: {
22
+ return draftState;
23
+ }
24
+ }
25
+ });
26
+
27
+ export default reducer;
28
+ export { initialState };
@@ -0,0 +1,25 @@
1
+ import AddLogoDialog from '../LogoModalStepper/AddLogoDialog';
2
+ import PendingLogoDialog from '../LogoModalStepper/PendingLogoDialog';
3
+
4
+ const stepper = {
5
+ upload: {
6
+ Component: AddLogoDialog,
7
+ modalTitle: {
8
+ id: 'Settings.application.customization.modal.upload',
9
+ defaultMessage: 'Upload logo',
10
+ },
11
+ next: 'pending',
12
+ prev: null,
13
+ },
14
+ pending: {
15
+ Component: PendingLogoDialog,
16
+ modalTitle: {
17
+ id: 'Settings.application.customization.modal.pending',
18
+ defaultMessage: 'Pending logo',
19
+ },
20
+ next: null,
21
+ prev: 'upload',
22
+ },
23
+ };
24
+
25
+ export default stepper;