@strapi/admin 4.6.0 → 4.7.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/.browserslistrc +2 -1
  2. package/admin/src/assets/images/onboarding-preview.png +0 -0
  3. package/admin/src/components/AuthenticatedApp/utils/api.js +5 -4
  4. package/admin/src/components/LeftMenu/index.js +9 -3
  5. package/admin/src/content-manager/components/CollectionTypeFormWrapper/index.js +18 -16
  6. package/admin/src/content-manager/components/DynamicTable/CellContent/RelationMultiple/index.js +5 -5
  7. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/findLeafByPathAndReplace.js +1 -3
  8. package/admin/src/content-manager/components/EditViewDataManagerProvider/utils/schema.js +6 -5
  9. package/admin/src/content-manager/components/InputUID/index.js +4 -4
  10. package/admin/src/content-manager/components/Inputs/index.js +0 -2
  11. package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +35 -14
  12. package/admin/src/content-manager/hooks/useFetchContentTypeLayout/index.js +4 -3
  13. package/admin/src/content-manager/hooks/useLazyComponents/index.js +9 -13
  14. package/admin/src/content-manager/hooks/useRelation/useRelation.js +4 -4
  15. package/admin/src/content-manager/pages/App/useModels.js +8 -3
  16. package/admin/src/content-manager/pages/App/utils/getContentTypeLinks.js +3 -2
  17. package/admin/src/content-manager/pages/ComponentSetttingsView/index.js +4 -4
  18. package/admin/src/content-manager/pages/EditSettingsView/utils/api.js +4 -2
  19. package/admin/src/content-manager/pages/ListSettingsView/utils/api.js +4 -2
  20. package/admin/src/content-manager/pages/ListView/index.js +9 -9
  21. package/admin/src/core/utils/index.js +0 -1
  22. package/admin/src/hooks/useFetchEnabledPlugins/utils/api.js +3 -2
  23. package/admin/src/hooks/useInjectReducer/index.js +1 -0
  24. package/admin/src/hooks/useInjectReducer/useInjectReducer.js +19 -0
  25. package/admin/src/hooks/useRegenerate/index.js +4 -4
  26. package/admin/src/hooks/useRolesList/index.js +5 -3
  27. package/admin/src/hooks/useSettingsMenu/utils/defaultGlobalLinks.js +7 -0
  28. package/admin/src/index.js +4 -3
  29. package/admin/src/pages/Admin/Onboarding/constants.js +46 -0
  30. package/admin/src/pages/Admin/Onboarding/index.js +161 -89
  31. package/admin/src/pages/Admin/index.js +5 -2
  32. package/admin/src/pages/ProfilePage/utils/api.js +5 -3
  33. package/admin/src/pages/SettingsPage/{pages/Users/ListPage → components}/Filters/index.js +0 -0
  34. package/admin/src/pages/SettingsPage/{pages/ApiTokens/EditView/components → components/Tokens}/FormHead/index.js +36 -19
  35. package/admin/src/pages/SettingsPage/components/Tokens/FormiTokenContainer/LifeSpanInput.js +96 -0
  36. package/admin/src/pages/SettingsPage/components/Tokens/LifeSpanInput/index.js +98 -0
  37. package/admin/src/pages/SettingsPage/components/Tokens/Regenerate/index.js +73 -0
  38. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/DefaultButton/index.js +1 -1
  39. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/DeleteButton/index.js +1 -1
  40. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/ReadButton/index.js +0 -0
  41. package/admin/src/pages/SettingsPage/{pages/ApiTokens/ListView/DynamicTable → components/Tokens/Table}/UpdateButton/index.js +0 -0
  42. package/admin/src/pages/SettingsPage/components/Tokens/Table/index.js +135 -0
  43. package/admin/src/pages/SettingsPage/{pages/ApiTokens/EditView/components/ContentBox → components/Tokens/TokenBox}/index.js +17 -17
  44. package/admin/src/pages/SettingsPage/components/Tokens/TokenDescription/index.js +51 -0
  45. package/admin/src/pages/SettingsPage/components/Tokens/TokenName/index.js +46 -0
  46. package/admin/src/pages/SettingsPage/components/Tokens/TokenTypeSelect/index.js +69 -0
  47. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/CollapsableContentType/index.js +5 -3
  48. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormApiTokenContainer/index.js +52 -142
  49. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/Regenerate/index.js +5 -1
  50. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +43 -19
  51. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +9 -16
  52. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/api.js +5 -3
  53. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/components/FormTransferTokenContainer/index.js +105 -0
  54. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/components/LoadingView/index.js +50 -0
  55. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/index.js +201 -0
  56. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/getDateOfExpiration.js +16 -0
  57. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/index.js +4 -0
  58. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/utils/schema.js +10 -0
  59. package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/index.js +182 -0
  60. package/admin/src/pages/SettingsPage/pages/TransferTokens/ListView/utils/tableHeaders.js +48 -0
  61. package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedCreateView/index.js +14 -0
  62. package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedEditView/index.js +14 -0
  63. package/admin/src/pages/SettingsPage/pages/TransferTokens/ProtectedListView/index.js +12 -0
  64. package/admin/src/pages/SettingsPage/pages/Users/EditPage/utils/api.js +6 -3
  65. package/admin/src/pages/SettingsPage/pages/Users/ListPage/ModalForm/index.js +9 -3
  66. package/admin/src/pages/SettingsPage/pages/Users/ListPage/index.js +1 -1
  67. package/admin/src/pages/SettingsPage/pages/Users/ListPage/utils/api.js +6 -3
  68. package/admin/src/pages/SettingsPage/pages/Users/components/SelectRoles/index.js +3 -2
  69. package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/index.js +3 -2
  70. package/admin/src/pages/SettingsPage/utils/defaultRoutes.js +33 -0
  71. package/admin/src/permissions/defaultPermissions.js +8 -0
  72. package/admin/src/translations/en.json +25 -6
  73. package/admin/src/translations/eu.json +796 -0
  74. package/admin/src/translations/languageNativeNames.js +1 -0
  75. package/admin/src/translations/ru.json +9 -9
  76. package/build/1412.936ed920.chunk.js +159 -0
  77. package/build/1683.c8aa7b7c.chunk.js +268 -0
  78. package/build/19eb2dfcf2603eb55733.png +0 -0
  79. package/build/2607.2e48dbf8.chunk.js +66 -0
  80. package/build/2743.6d1632f9.chunk.js +45 -0
  81. package/build/3075.dc3894fe.chunk.js +108 -0
  82. package/build/3632.0317b618.chunk.js +138 -0
  83. package/build/4649.15cc0afe.chunk.js +30 -0
  84. package/build/{5910.a5374848.chunk.js → 4855.bd092921.chunk.js} +65 -65
  85. package/build/7259.aa68d808.chunk.js +1 -0
  86. package/build/7407.883fb1f5.chunk.js +1 -0
  87. package/build/9707.7290fd92.chunk.js +96 -0
  88. package/build/Admin-authenticatedApp.f29f6021.chunk.js +79 -0
  89. package/build/{Admin_homePage.79ab880c.chunk.js → Admin_homePage.b1730882.chunk.js} +1 -1
  90. package/build/{Admin_marketplace.eabf21b2.chunk.js → Admin_marketplace.ea0316c2.chunk.js} +2 -2
  91. package/build/Admin_pluginsPage.5c24f963.chunk.js +6 -0
  92. package/build/Admin_profilePage.59af1978.chunk.js +15 -0
  93. package/build/Admin_settingsPage.178dc6e3.chunk.js +178 -0
  94. package/build/admin-app.77a50e1f.chunk.js +112 -0
  95. package/build/admin-edit-roles-page.446b69dc.chunk.js +1 -0
  96. package/build/admin-edit-users.2ed69bfd.chunk.js +10 -0
  97. package/build/admin-users.fc003b10.chunk.js +11 -0
  98. package/build/{api-tokens-create-page.0e686c30.chunk.js → api-tokens-create-page.0db3aec1.chunk.js} +1 -1
  99. package/build/{api-tokens-edit-page.d6c7487b.chunk.js → api-tokens-edit-page.671e0e26.chunk.js} +1 -1
  100. package/build/api-tokens-list-page.7387102c.chunk.js +16 -0
  101. package/build/audit-logs-settings-page.c3dce30d.chunk.js +1 -0
  102. package/build/content-manager.42b24d46.chunk.js +1139 -0
  103. package/build/{content-type-builder-list-view.4243b2b1.chunk.js → content-type-builder-list-view.79e84b36.chunk.js} +1 -6
  104. package/build/{content-type-builder.365b6bf4.chunk.js → content-type-builder.855db321.chunk.js} +16 -15
  105. package/build/{email-settings-page.379552b1.chunk.js → email-settings-page.d1fcc7a3.chunk.js} +4 -9
  106. package/build/en-json.b0748970.chunk.js +1 -0
  107. package/build/eu-json.fceecd8b.chunk.js +1 -0
  108. package/build/i18n-settings-page.b8d8753e.chunk.js +60 -0
  109. package/build/index.html +1 -1
  110. package/build/main.1022ed01.js +4393 -0
  111. package/build/ru-json.aa5cd123.chunk.js +1 -0
  112. package/build/runtime~main.84941a97.js +2 -0
  113. package/build/sso-settings-page.b85ad080.chunk.js +41 -0
  114. package/build/transfer-tokens-create-page.16e23791.chunk.js +1 -0
  115. package/build/transfer-tokens-edit-page.3886c973.chunk.js +1 -0
  116. package/build/transfer-tokens-list-page.e8010a89.chunk.js +16 -0
  117. package/build/upload-settings.ef64bbf9.chunk.js +84 -0
  118. package/build/upload.c5730dfa.chunk.js +33 -0
  119. package/build/users-advanced-settings-page.fce9908e.chunk.js +8 -0
  120. package/build/users-email-settings-page.343d0ad2.chunk.js +23 -0
  121. package/build/users-providers-settings-page.e5a9a3f1.chunk.js +99 -0
  122. package/build/users-roles-settings-page.66312f31.chunk.js +30 -0
  123. package/build/webhook-edit-page.73e51e64.chunk.js +75 -0
  124. package/build/{webhook-list-page.f75ba3f2.chunk.js → webhook-list-page.1134f130.chunk.js} +1 -1
  125. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/ComboboxFilter/index.js +41 -0
  126. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/Modal/ActionBody.js +1 -3
  127. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/TableRows/index.js +1 -1
  128. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/hooks/useAuditLogsData.js +47 -0
  129. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/index.js +30 -31
  130. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/utils/getActionTypesDefaultMessages.js +7 -9
  131. package/ee/admin/pages/SettingsPage/pages/AuditLogs/ListView/utils/getDisplayedFilters.js +88 -0
  132. package/ee/admin/pages/SettingsPage/pages/Roles/ListPage/index.js +4 -2
  133. package/ee/server/migrations/audit-logs-table.js +45 -0
  134. package/ee/server/register.js +2 -0
  135. package/ee/server/services/audit-logs.js +11 -1
  136. package/package.json +30 -30
  137. package/server/bootstrap.js +2 -0
  138. package/server/config/admin-actions.js +48 -0
  139. package/server/content-types/index.js +2 -0
  140. package/server/content-types/transfer-token-permission.js +36 -0
  141. package/server/content-types/transfer-token.js +66 -0
  142. package/server/controllers/admin.js +16 -0
  143. package/server/controllers/api-token.js +4 -5
  144. package/server/controllers/index.js +1 -0
  145. package/server/controllers/transfer/index.js +13 -0
  146. package/server/controllers/transfer/runner.js +24 -0
  147. package/server/controllers/transfer/token.js +131 -0
  148. package/server/register.js +2 -9
  149. package/server/routes/index.js +2 -0
  150. package/server/routes/transfer.js +95 -0
  151. package/server/services/api-token.js +2 -3
  152. package/server/services/constants.js +6 -0
  153. package/server/services/index.js +1 -0
  154. package/server/services/transfer/index.js +6 -0
  155. package/server/services/transfer/permission.js +22 -0
  156. package/server/services/transfer/token.js +409 -0
  157. package/server/strategies/api-token.js +4 -2
  158. package/server/strategies/data-transfer.js +107 -0
  159. package/server/strategies/index.js +1 -0
  160. package/server/utils/index.d.ts +2 -0
  161. package/server/validation/api-tokens.js +1 -6
  162. package/server/validation/transfer/index.js +5 -0
  163. package/server/validation/transfer/token.js +34 -0
  164. package/admin/src/content-manager/components/InputJSON/FieldWrapper.js +0 -40
  165. package/admin/src/content-manager/components/InputJSON/Label.js +0 -35
  166. package/admin/src/content-manager/components/InputJSON/components.js +0 -36
  167. package/admin/src/content-manager/components/InputJSON/index.js +0 -223
  168. package/admin/src/content-manager/components/InputJSON/jsonlint.js +0 -680
  169. package/admin/src/core/utils/axiosInstance.js +0 -40
  170. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/components/FormBody/index.js +0 -78
  171. package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/index.js +0 -112
  172. package/build/2607.ce06608e.chunk.js +0 -66
  173. package/build/2743.dea372fb.chunk.js +0 -42
  174. package/build/3075.03ebe93d.chunk.js +0 -115
  175. package/build/3632.963ac97d.chunk.js +0 -138
  176. package/build/4318.8cb388a5.chunk.js +0 -30
  177. package/build/4656.a0d43cca.chunk.js +0 -159
  178. package/build/8633.4af74a50.chunk.js +0 -1
  179. package/build/9641.a311b612.chunk.js +0 -276
  180. package/build/9707.62831b4d.chunk.js +0 -101
  181. package/build/Admin-authenticatedApp.50dc27f9.chunk.js +0 -75
  182. package/build/Admin_pluginsPage.953e796b.chunk.js +0 -6
  183. package/build/Admin_profilePage.5c2efda5.chunk.js +0 -15
  184. package/build/Admin_settingsPage.19cfb9ca.chunk.js +0 -178
  185. package/build/admin-app.34295b50.chunk.js +0 -112
  186. package/build/admin-edit-roles-page.d50d9654.chunk.js +0 -1
  187. package/build/admin-edit-users.912b856d.chunk.js +0 -10
  188. package/build/admin-users.e36e7111.chunk.js +0 -11
  189. package/build/api-tokens-list-page.1cd86136.chunk.js +0 -16
  190. package/build/audit-logs-settings-page.308a6250.chunk.js +0 -1
  191. package/build/codemirror-addon-closebrackets.71aa4bbd.chunk.js +0 -2
  192. package/build/codemirror-addon-lint-js.405f70fb.chunk.js +0 -1
  193. package/build/codemirror-addon-lint.8487ad3d.chunk.js +0 -1
  194. package/build/codemirror-addon-mark-selection.1928c849.chunk.js +0 -1
  195. package/build/codemirror-css.359a2a4b.chunk.js +0 -345
  196. package/build/codemirror-javacript.af237b68.chunk.js +0 -1
  197. package/build/codemirror-theme.2fe63a16.chunk.js +0 -33
  198. package/build/content-manager.851f40ce.chunk.js +0 -1170
  199. package/build/en-json.38d182e5.chunk.js +0 -1
  200. package/build/i18n-settings-page.3ab28b1a.chunk.js +0 -65
  201. package/build/main.9f31732e.js +0 -4454
  202. package/build/ru-json.3b411a39.chunk.js +0 -1
  203. package/build/runtime~main.2b8e2318.js +0 -2
  204. package/build/sso-settings-page.b64a44e8.chunk.js +0 -41
  205. package/build/upload-settings.6c26ff37.chunk.js +0 -89
  206. package/build/upload.2c69d238.chunk.js +0 -38
  207. package/build/users-advanced-settings-page.c4270682.chunk.js +0 -13
  208. package/build/users-email-settings-page.60422a2f.chunk.js +0 -28
  209. package/build/users-providers-settings-page.e1834060.chunk.js +0 -104
  210. package/build/users-roles-settings-page.3ef35132.chunk.js +0 -30
  211. package/build/webhook-edit-page.c0080dc1.chunk.js +0 -75
@@ -1,13 +1,14 @@
1
- import { axiosInstance } from '../../../../core/utils';
1
+ import { getFetchClient } from '@strapi/helper-plugin';
2
2
  import generateModelsLinks from './generateModelsLinks';
3
3
  import checkPermissions from './checkPermissions';
4
4
  import { getRequestUrl } from '../../../utils';
5
5
 
6
6
  const getContentTypeLinks = async (models, userPermissions, toggleNotification) => {
7
+ const { get } = getFetchClient();
7
8
  try {
8
9
  const {
9
10
  data: { data: contentTypeConfigurations },
10
- } = await axiosInstance.get(getRequestUrl('content-types-settings'));
11
+ } = await get(getRequestUrl('content-types-settings'));
11
12
 
12
13
  const { collectionTypesSectionLinks, singleTypesSectionLinks } = generateModelsLinks(
13
14
  models,
@@ -1,9 +1,8 @@
1
1
  import React, { memo, useEffect, useMemo, useReducer } from 'react';
2
2
  import { useParams } from 'react-router-dom';
3
- import { CheckPagePermissions, LoadingIndicatorPage } from '@strapi/helper-plugin';
3
+ import { CheckPagePermissions, LoadingIndicatorPage, useFetchClient } from '@strapi/helper-plugin';
4
4
  import { useSelector, shallowEqual } from 'react-redux';
5
5
  import axios from 'axios';
6
- import { axiosInstance } from '../../../core/utils';
7
6
  import { getRequestUrl, mergeMetasWithSchema } from '../../utils';
8
7
  import { makeSelectModelAndComponentSchemas } from '../App/selectors';
9
8
  import permissions from '../../../permissions';
@@ -18,6 +17,7 @@ const ComponentSettingsView = () => {
18
17
  const schemasSelector = useMemo(makeSelectModelAndComponentSchemas, []);
19
18
  const { schemas } = useSelector((state) => schemasSelector(state), shallowEqual);
20
19
  const { uid } = useParams();
20
+ const { get } = useFetchClient();
21
21
 
22
22
  useEffect(() => {
23
23
  const CancelToken = axios.CancelToken;
@@ -29,7 +29,7 @@ const ComponentSettingsView = () => {
29
29
 
30
30
  const {
31
31
  data: { data },
32
- } = await axiosInstance.get(getRequestUrl(`components/${uid}/configuration`), {
32
+ } = await get(getRequestUrl(`components/${uid}/configuration`), {
33
33
  cancelToken: source.token,
34
34
  });
35
35
 
@@ -48,7 +48,7 @@ const ComponentSettingsView = () => {
48
48
  return () => {
49
49
  source.cancel('Operation canceled by the user.');
50
50
  };
51
- }, [uid, schemas]);
51
+ }, [uid, schemas, get]);
52
52
 
53
53
  if (isLoading) {
54
54
  return <LoadingIndicatorPage />;
@@ -1,8 +1,10 @@
1
- import { axiosInstance } from '../../../../core/utils';
1
+ import { getFetchClient } from '@strapi/helper-plugin';
2
2
  import { getRequestUrl } from '../../../utils';
3
3
 
4
4
  const putCMSettingsEV = (body, slug, isContentTypeView) => {
5
- return axiosInstance.put(
5
+ const { put } = getFetchClient();
6
+
7
+ return put(
6
8
  getRequestUrl(
7
9
  isContentTypeView ? `content-types/${slug}/configuration` : `components/${slug}/configuration`
8
10
  ),
@@ -1,8 +1,10 @@
1
- import { axiosInstance } from '../../../../core/utils';
1
+ import { getFetchClient } from '@strapi/helper-plugin';
2
2
  import { getRequestUrl } from '../../../utils';
3
3
 
4
4
  const putCMSettingsLV = (body, slug) => {
5
- return axiosInstance.put(getRequestUrl(`content-types/${slug}/configuration`), body);
5
+ const { put } = getFetchClient();
6
+
7
+ return put(getRequestUrl(`content-types/${slug}/configuration`), body);
6
8
  };
7
9
 
8
10
  export default putCMSettingsLV;
@@ -14,6 +14,7 @@ import {
14
14
  NoPermissions,
15
15
  CheckPermissions,
16
16
  SearchURLQuery,
17
+ useFetchClient,
17
18
  useFocusWhenNavigate,
18
19
  useQueryParams,
19
20
  useNotification,
@@ -33,8 +34,6 @@ import ArrowLeft from '@strapi/icons/ArrowLeft';
33
34
  import Plus from '@strapi/icons/Plus';
34
35
  import Cog from '@strapi/icons/Cog';
35
36
 
36
- import { axiosInstance } from '../../../core/utils';
37
-
38
37
  import DynamicTable from '../../components/DynamicTable';
39
38
  import AttributeFilter from '../../components/AttributeFilter';
40
39
  import { InjectionZone } from '../../../shared/components';
@@ -97,6 +96,8 @@ function ListView({
97
96
  const { formatMessage } = useIntl();
98
97
  const contentType = layout.contentType;
99
98
  const hasDraftAndPublish = get(contentType, 'options.draftAndPublish', false);
99
+ const fetchClient = useFetchClient();
100
+ const { post, del } = fetchClient;
100
101
 
101
102
  // FIXME
102
103
  // Using a ref to avoid requests being fired multiple times on slug on change
@@ -112,7 +113,7 @@ function ListView({
112
113
 
113
114
  const {
114
115
  data: { results, pagination: paginationResult },
115
- } = await axiosInstance.get(endPoint, opts);
116
+ } = await fetchClient.get(endPoint, opts);
116
117
 
117
118
  notifyStatus(
118
119
  formatMessage(
@@ -154,13 +155,13 @@ function ListView({
154
155
  });
155
156
  }
156
157
  },
157
- [formatMessage, getData, getDataSucceeded, notifyStatus, push, toggleNotification]
158
+ [formatMessage, getData, getDataSucceeded, notifyStatus, push, toggleNotification, fetchClient]
158
159
  );
159
160
 
160
161
  const handleConfirmDeleteAllData = useCallback(
161
162
  async (ids) => {
162
163
  try {
163
- await axiosInstance.post(getRequestUrl(`collection-types/${slug}/actions/bulkDelete`), {
164
+ await post(getRequestUrl(`collection-types/${slug}/actions/bulkDelete`), {
164
165
  ids,
165
166
  });
166
167
 
@@ -174,13 +175,13 @@ function ListView({
174
175
  });
175
176
  }
176
177
  },
177
- [fetchData, params, slug, toggleNotification]
178
+ [fetchData, params, slug, toggleNotification, post]
178
179
  );
179
180
 
180
181
  const handleConfirmDeleteData = useCallback(
181
182
  async (idToDelete) => {
182
183
  try {
183
- await axiosInstance.delete(getRequestUrl(`collection-types/${slug}/${idToDelete}`));
184
+ await del(getRequestUrl(`collection-types/${slug}/${idToDelete}`));
184
185
 
185
186
  const requestUrl = getRequestUrl(`collection-types/${slug}${params}`);
186
187
  fetchData(requestUrl);
@@ -202,7 +203,7 @@ function ListView({
202
203
  });
203
204
  }
204
205
  },
205
- [slug, params, fetchData, toggleNotification, formatMessage]
206
+ [slug, params, fetchData, toggleNotification, formatMessage, del]
206
207
  );
207
208
 
208
209
  useEffect(() => {
@@ -221,7 +222,6 @@ function ListView({
221
222
 
222
223
  source.cancel('Operation canceled by the user.');
223
224
  };
224
- // eslint-disable-next-line react-hooks/exhaustive-deps
225
225
  }, [canRead, getData, slug, params, getDataSucceeded, fetchData]);
226
226
 
227
227
  const defaultHeaderLayoutTitle = formatMessage({
@@ -1,3 +1,2 @@
1
- export { default as axiosInstance } from './axiosInstance';
2
1
  export { default as basename } from './basename';
3
2
  export { default as createHook } from './createHook';
@@ -1,7 +1,8 @@
1
- import { axiosInstance } from '../../../core/utils';
1
+ import { getFetchClient } from '@strapi/helper-plugin';
2
2
 
3
3
  const fetchEnabledPlugins = async () => {
4
- const { data } = await axiosInstance.get('/admin/plugins');
4
+ const { get } = getFetchClient();
5
+ const { data } = await get('/admin/plugins');
5
6
 
6
7
  return data;
7
8
  };
@@ -0,0 +1 @@
1
+ export * from './useInjectReducer';
@@ -0,0 +1,19 @@
1
+ import { useEffect } from 'react';
2
+ import { useStore } from 'react-redux';
3
+
4
+ /**
5
+ * Inject a new reducer into the global redux-store.
6
+ *
7
+ * @export
8
+ * @param {string} namespace - Store namespace of the injected reducer
9
+ * @param {Function} reducer - Reducer function
10
+ * @return void
11
+ */
12
+
13
+ export function useInjectReducer(namespace, reducer) {
14
+ const store = useStore();
15
+
16
+ useEffect(() => {
17
+ store.injectReducer(namespace, reducer);
18
+ }, [store, namespace, reducer]);
19
+ }
@@ -1,11 +1,11 @@
1
1
  import { useState } from 'react';
2
2
  import { get } from 'lodash';
3
- import { useNotification } from '@strapi/helper-plugin';
4
- import { axiosInstance } from '../../core/utils';
3
+ import { useFetchClient, useNotification } from '@strapi/helper-plugin';
5
4
 
6
- const useRegenerate = (id, onRegenerate) => {
5
+ const useRegenerate = (url, id, onRegenerate) => {
7
6
  const [isLoadingConfirmation, setIsLoadingConfirmation] = useState(false);
8
7
  const toggleNotification = useNotification();
8
+ const { post } = useFetchClient();
9
9
 
10
10
  const regenerateData = async () => {
11
11
  try {
@@ -13,7 +13,7 @@ const useRegenerate = (id, onRegenerate) => {
13
13
  data: {
14
14
  data: { accessKey },
15
15
  },
16
- } = await axiosInstance.post(`/admin/api-tokens/${id}/regenerate`);
16
+ } = await post(`${url}${id}/regenerate`);
17
17
  setIsLoadingConfirmation(false);
18
18
  onRegenerate(accessKey);
19
19
  } catch (error) {
@@ -1,7 +1,6 @@
1
1
  import { useEffect, useReducer, useCallback } from 'react';
2
- import { useNotification } from '@strapi/helper-plugin';
2
+ import { getFetchClient, useNotification } from '@strapi/helper-plugin';
3
3
  import get from 'lodash/get';
4
- import { axiosInstance } from '../../core/utils';
5
4
  import init from './init';
6
5
  import reducer, { initialState } from './reducer';
7
6
 
@@ -19,6 +18,9 @@ const useRolesList = (shouldFetchData = true) => {
19
18
  }, [shouldFetchData]);
20
19
 
21
20
  const fetchRolesList = useCallback(async () => {
21
+ // TODO: evaluate to replace it with a useFetchClient when we work on the useCallback to remove
22
+ const fetchClient = getFetchClient();
23
+
22
24
  try {
23
25
  dispatch({
24
26
  type: 'GET_DATA',
@@ -26,7 +28,7 @@ const useRolesList = (shouldFetchData = true) => {
26
28
 
27
29
  const {
28
30
  data: { data },
29
- } = await axiosInstance.get('/admin/roles');
31
+ } = await fetchClient.get('/admin/roles');
30
32
 
31
33
  dispatch({
32
34
  type: 'GET_DATA_SUCCEEDED',
@@ -22,6 +22,13 @@ const defaultGlobalLinks = [
22
22
  isDisplayed: false,
23
23
  permissions: adminPermissions.settings['api-tokens'].main,
24
24
  },
25
+ {
26
+ intlLabel: { id: 'Settings.transferTokens.title', defaultMessage: 'Transfer Tokens' },
27
+ to: '/settings/transfer-tokens?sort=name:ASC',
28
+ id: 'transfer-tokens',
29
+ isDisplayed: false,
30
+ permissions: adminPermissions.settings['transfer-tokens'].main,
31
+ },
25
32
  ];
26
33
 
27
34
  export default defaultGlobalLinks;
@@ -1,7 +1,7 @@
1
1
  import ReactDOM from 'react-dom';
2
- import appCustomisations from './app';
2
+ import { getFetchClient } from '@strapi/helper-plugin';
3
3
  import { Components, Fields, Middlewares, Reducers } from './core/apis';
4
- import { axiosInstance } from './core/utils';
4
+ import appCustomisations from './app';
5
5
  // eslint-disable-next-line import/extensions
6
6
  import plugins from './plugins';
7
7
  import appReducers from './reducers';
@@ -29,12 +29,13 @@ const reducers = Reducers({ appReducers });
29
29
  const MOUNT_NODE = document.getElementById('app');
30
30
 
31
31
  const run = async () => {
32
+ const { get } = getFetchClient();
32
33
  try {
33
34
  const {
34
35
  data: {
35
36
  data: { isEE, features },
36
37
  },
37
- } = await axiosInstance.get('/admin/project-type');
38
+ } = await get('/admin/project-type');
38
39
 
39
40
  window.strapi.isEE = isEE;
40
41
  window.strapi.features = {
@@ -0,0 +1,46 @@
1
+ import { Book, PaperPlane } from '@strapi/icons';
2
+
3
+ export const VIDEO_LINKS = [
4
+ {
5
+ label: {
6
+ id: 'app.components.Onboarding.link.build-content',
7
+ defaultMessage: 'Build a content architecture',
8
+ },
9
+ href: 'https://www.youtube.com/watch?v=G9GjN0RxhkE',
10
+ duration: '5:48',
11
+ },
12
+ {
13
+ label: {
14
+ id: 'app.components.Onboarding.link.manage-content',
15
+ defaultMessage: 'Add & manage content',
16
+ },
17
+ href: 'https://www.youtube.com/watch?v=DEZw4KbybAI',
18
+ duration: '3:18',
19
+ },
20
+ {
21
+ label: { id: 'app.components.Onboarding.link.manage-media', defaultMessage: 'Manage media' },
22
+ href: 'https://www.youtube.com/watch?v=-61MuiMQb38',
23
+ duration: '3:41',
24
+ },
25
+ ];
26
+
27
+ export const WATCH_MORE = {
28
+ href: 'https://www.youtube.com/playlist?list=PL7Q0DQYATmvidz6lEmwE5nIcOAYagxWqq',
29
+ label: {
30
+ id: 'app.components.Onboarding.link.more-videos',
31
+ defaultMessage: 'Watch more videos',
32
+ },
33
+ };
34
+
35
+ export const DOCUMENTATION_LINKS = [
36
+ {
37
+ label: { id: 'global.documentation', defaultMessage: 'documentation' },
38
+ href: 'https://docs.strapi.io',
39
+ icon: Book,
40
+ },
41
+ {
42
+ label: { id: 'app.static.links.cheatsheet', defaultMessage: 'cheatsheet' },
43
+ href: 'https://strapi-showcase.s3-us-west-2.amazonaws.com/CheatSheet.pdf',
44
+ icon: PaperPlane,
45
+ },
46
+ ];
@@ -1,92 +1,91 @@
1
- import React, { useState } from 'react';
1
+ import React, { useRef, useState } from 'react';
2
2
  import styled from 'styled-components';
3
3
  import { useIntl } from 'react-intl';
4
- import { Box, Flex, FocusTrap, Typography, Icon, Stack } from '@strapi/design-system';
5
- import { Book, Cross, Information, Question } from '@strapi/icons';
6
- import { pxToRem } from '@strapi/helper-plugin';
7
-
8
- import { useConfigurations } from '../../../hooks';
9
-
10
- const OnboardingWrapper = styled(Box)`
11
- position: fixed;
12
- bottom: ${({ theme }) => theme.spaces[2]};
13
- right: ${({ theme }) => theme.spaces[2]};
14
- `;
15
-
16
- const Button = styled(Box)`
17
- width: ${({ theme }) => theme.spaces[8]};
18
- height: ${({ theme }) => theme.spaces[8]};
19
- background: ${({ theme }) => theme.colors.primary600};
20
- box-shadow: ${({ theme }) => theme.shadows.tableShadow};
4
+ import {
5
+ Box,
6
+ Button,
7
+ Divider,
8
+ Flex,
9
+ FocusTrap,
10
+ Icon,
11
+ Portal,
12
+ PopoverPrimitives,
13
+ Stack,
14
+ Typography,
15
+ VisuallyHidden,
16
+ } from '@strapi/design-system';
17
+ import { Cross, Play, Question } from '@strapi/icons';
18
+
19
+ import onboardingPreview from '../../../assets/images/onboarding-preview.png';
20
+ import { VIDEO_LINKS, DOCUMENTATION_LINKS, WATCH_MORE } from './constants';
21
+
22
+ // TODO: use new Button props derived from Box props with next DS release
23
+ const HelperButton = styled(Button)`
21
24
  border-radius: 50%;
22
-
23
- svg path {
24
- fill: ${({ theme }) => theme.colors.buttonNeutral0};
25
- }
25
+ padding: ${({ theme }) => theme.spaces[3]};
26
+ /* Resetting 2rem height defined by Button component */
27
+ height: 100%;
26
28
  `;
27
29
 
28
- const LinksWrapper = styled(Box)`
29
- bottom: ${({ theme }) => `${theme.spaces[9]}`};
30
- min-width: ${200 / 16}rem;
31
- position: absolute;
32
- right: 0;
30
+ const IconWrapper = styled(Flex)`
31
+ transform: translate(-50%, -50%);
33
32
  `;
34
33
 
35
- const StyledLink = styled(Flex)`
34
+ const VideoLinkWrapper = styled(Flex)`
36
35
  text-decoration: none;
37
36
 
38
- svg path {
39
- fill: ${({ theme }) => theme.colors.neutral600};
37
+ :focus-visible {
38
+ outline-offset: ${({ theme }) => `-${theme.spaces[1]}`};
40
39
  }
41
40
 
42
- &:focus,
43
- &:hover {
44
- background: ${({ theme }) => theme.colors.neutral100};
41
+ :hover {
42
+ background: ${({ theme }) => theme.colors.primary100};
45
43
 
46
- svg path {
47
- fill: ${({ theme }) => theme.colors.neutral700};
44
+ /* Hover style for the number displayed */
45
+ ${Typography}:first-child {
46
+ color: ${({ theme }) => theme.colors.primary500};
48
47
  }
49
48
 
50
- ${[Typography]} {
51
- color: ${({ theme }) => theme.colors.neutral700};
49
+ /* Hover style for the label */
50
+ ${Typography}:nth-child(1) {
51
+ color: ${({ theme }) => theme.colors.primary600};
52
52
  }
53
53
  }
54
54
  `;
55
55
 
56
+ const Preview = styled.img`
57
+ width: ${({ theme }) => theme.spaces[10]};
58
+ height: ${({ theme }) => theme.spaces[8]};
59
+ /* Same overlay used in ModalLayout */
60
+ background: ${({ theme }) => `${theme.colors.neutral800}1F`};
61
+ border-radius: ${({ theme }) => theme.borderRadius};
62
+ `;
63
+
64
+ const TypographyLineHeight = styled(Typography)`
65
+ /* line height of label and watch more to 1 so they can be better aligned visually */
66
+ line-height: 1;
67
+ `;
68
+
69
+ const TextLink = styled(TypographyLineHeight)`
70
+ text-decoration: none;
71
+
72
+ :hover {
73
+ text-decoration: underline;
74
+ }
75
+ `;
76
+
56
77
  const Onboarding = () => {
78
+ const triggerRef = useRef();
57
79
  const [isOpen, setIsOpen] = useState(false);
58
80
  const { formatMessage } = useIntl();
59
- const { showTutorials } = useConfigurations();
60
-
61
- if (!showTutorials) {
62
- return null;
63
- }
64
81
 
65
- const STATIC_LINKS = [
66
- {
67
- Icon: <Book />,
68
- label: formatMessage({
69
- id: 'global.documentation',
70
- defaultMessage: 'Documentation',
71
- }),
72
- destination: 'https://docs.strapi.io',
73
- },
74
- {
75
- Icon: <Information />,
76
- label: formatMessage({ id: 'app.static.links.cheatsheet', defaultMessage: 'CheatSheet' }),
77
- destination: 'https://strapi-showcase.s3-us-west-2.amazonaws.com/CheatSheet.pdf',
78
- },
79
- ];
80
-
81
- const handleClick = () => {
82
+ const handlePopoverVisibility = () => {
82
83
  setIsOpen((prev) => !prev);
83
84
  };
84
85
 
85
86
  return (
86
- <OnboardingWrapper as="aside">
87
- <Button
88
- as="button"
89
- id="onboarding"
87
+ <Box as="aside" position="fixed" bottom={2} right={2}>
88
+ <HelperButton
90
89
  aria-label={formatMessage(
91
90
  isOpen
92
91
  ? {
@@ -98,37 +97,110 @@ const Onboarding = () => {
98
97
  defaultMessage: 'Open help menu',
99
98
  }
100
99
  )}
101
- onClick={handleClick}
100
+ onClick={handlePopoverVisibility}
101
+ ref={triggerRef}
102
102
  >
103
- <Icon as={isOpen ? Cross : Question} height={pxToRem(16)} width={pxToRem(16)} />
104
- </Button>
103
+ <Icon as={isOpen ? Cross : Question} color="buttonNeutral0" />
104
+ </HelperButton>
105
105
 
106
- {/* FIX ME - replace with popover when overflow popover is fixed
107
- + when v4 mockups for onboarding component are ready */}
108
106
  {isOpen && (
109
- <FocusTrap onEscape={handleClick}>
110
- <LinksWrapper background="neutral0" hasRadius shadow="tableShadow" padding={2}>
111
- {STATIC_LINKS.map((link) => (
112
- <StyledLink
113
- as="a"
114
- key={link.label}
115
- rel="nofollow noreferrer noopener"
116
- target="_blank"
117
- href={link.destination}
118
- padding={2}
119
- hasRadius
120
- alignItems="center"
107
+ <Portal>
108
+ <PopoverPrimitives.Content
109
+ padding={0}
110
+ source={triggerRef}
111
+ placement="top-end"
112
+ spacing={12}
113
+ >
114
+ <FocusTrap onEscape={handlePopoverVisibility}>
115
+ <Flex
116
+ justifyContent="space-between"
117
+ paddingBottom={5}
118
+ paddingRight={6}
119
+ paddingLeft={6}
120
+ paddingTop={6}
121
121
  >
122
- <Stack horizontal spacing={2}>
123
- {link.Icon}
124
- <Typography color="neutral600">{link.label}</Typography>
125
- </Stack>
126
- </StyledLink>
127
- ))}
128
- </LinksWrapper>
129
- </FocusTrap>
122
+ <TypographyLineHeight fontWeight="bold">
123
+ {formatMessage({
124
+ id: 'app.components.Onboarding.title',
125
+ defaultMessage: 'Get started videos',
126
+ })}
127
+ </TypographyLineHeight>
128
+ <TextLink
129
+ as="a"
130
+ href={WATCH_MORE.href}
131
+ target="_blank"
132
+ rel="noreferrer noopener"
133
+ variant="pi"
134
+ textColor="primary600"
135
+ >
136
+ {formatMessage(WATCH_MORE.label)}
137
+ </TextLink>
138
+ </Flex>
139
+ <Divider />
140
+ {VIDEO_LINKS.map(({ href, duration, label }, index) => (
141
+ <VideoLinkWrapper
142
+ as="a"
143
+ href={href}
144
+ target="_blank"
145
+ rel="noreferrer noopener"
146
+ key={href}
147
+ hasRadius
148
+ paddingTop={4}
149
+ paddingBottom={4}
150
+ paddingLeft={6}
151
+ paddingRight={11}
152
+ >
153
+ <Box paddingRight={5}>
154
+ <Typography textColor="neutral200" variant="alpha">
155
+ {index + 1}
156
+ </Typography>
157
+ </Box>
158
+ <Box position="relative">
159
+ <Preview src={onboardingPreview} alt="" />
160
+ <IconWrapper
161
+ position="absolute"
162
+ top="50%"
163
+ left="50%"
164
+ background="primary600"
165
+ borderRadius="50%"
166
+ justifyContent="center"
167
+ width={6}
168
+ height={6}
169
+ >
170
+ <Icon as={Play} color="buttonNeutral0" width={3} height={3} />
171
+ </IconWrapper>
172
+ </Box>
173
+ <Flex direction="column" alignItems="start" paddingLeft={4}>
174
+ <Typography fontWeight="bold">{formatMessage(label)}</Typography>
175
+ <VisuallyHidden>:</VisuallyHidden>
176
+ <Typography textColor="neutral600" variant="pi">
177
+ {duration}
178
+ </Typography>
179
+ </Flex>
180
+ </VideoLinkWrapper>
181
+ ))}
182
+ <Stack spacing={2} paddingLeft={5} paddingTop={2} paddingBottom={5}>
183
+ {DOCUMENTATION_LINKS.map(({ label, href, icon }) => (
184
+ <Stack horizontal spacing={3} key={href}>
185
+ <Icon as={icon} color="primary600" />
186
+ <TextLink
187
+ as="a"
188
+ href={href}
189
+ target="_blank"
190
+ rel="noreferrer noopener"
191
+ variant="sigma"
192
+ textColor="primary700"
193
+ >
194
+ {formatMessage(label)}
195
+ </TextLink>
196
+ </Stack>
197
+ ))}
198
+ </Stack>
199
+ </FocusTrap>
200
+ </PopoverPrimitives.Content>
201
+ </Portal>
130
202
  )}
131
- </OnboardingWrapper>
203
+ </Box>
132
204
  );
133
205
  };
134
206
 
@@ -10,10 +10,11 @@ import { useTracking, LoadingIndicatorPage, useStrapiApp } from '@strapi/helper-
10
10
  import { useDispatch, useSelector } from 'react-redux';
11
11
  import { DndProvider } from 'react-dnd';
12
12
  import { HTML5Backend } from 'react-dnd-html5-backend';
13
+
13
14
  import GuidedTourModal from '../../components/GuidedTour/Modal';
14
15
  import LeftMenu from '../../components/LeftMenu';
15
16
  import AppLayout from '../../layouts/AppLayout';
16
- import { useMenu } from '../../hooks';
17
+ import { useMenu, useConfigurations } from '../../hooks';
17
18
  import { createRoute } from '../../utils';
18
19
  import { SET_APP_RUNTIME_STATUS } from '../App/constants';
19
20
  import Onboarding from './Onboarding';
@@ -65,6 +66,7 @@ const Admin = () => {
65
66
  useTrackUsage();
66
67
  const { isLoading, generalSectionLinks, pluginsSectionLinks } = useMenu();
67
68
  const { menu } = useStrapiApp();
69
+ const { showTutorials } = useConfigurations();
68
70
 
69
71
  const routes = useMemo(() => {
70
72
  return menu
@@ -106,7 +108,8 @@ const Admin = () => {
106
108
  </Switch>
107
109
  </Suspense>
108
110
  <GuidedTourModal />
109
- <Onboarding />
111
+
112
+ {showTutorials && <Onboarding />}
110
113
  </AppLayout>
111
114
  </DndProvider>
112
115
  );