@strapi/admin 4.12.6 → 4.12.7

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 (159) hide show
  1. package/admin/src/StrapiApp.js +1 -1
  2. package/admin/src/components/AuthenticatedApp/index.js +118 -0
  3. package/admin/src/components/AuthenticatedApp/utils/api.js +85 -0
  4. package/admin/src/components/AuthenticatedApp/utils/checkLatestStrapiVersion.js +11 -0
  5. package/admin/src/components/GuidedTour/Modal/index.js +3 -1
  6. package/admin/src/components/PluginsInitializer/index.js +68 -0
  7. package/admin/src/components/PluginsInitializer/init.js +11 -0
  8. package/admin/src/components/PluginsInitializer/reducer.js +22 -0
  9. package/admin/src/content-manager/pages/App/index.js +16 -5
  10. package/admin/src/content-manager/pages/EditView/Information/index.js +1 -1
  11. package/admin/src/content-manager/pages/ListView/components/BulkActionButtons/SelectedEntriesModal/index.js +2 -2
  12. package/admin/src/content-manager/pages/ListView/components/TableRows/index.js +1 -1
  13. package/admin/src/hooks/useSettingsForm/index.js +3 -14
  14. package/admin/src/hooks/useSettingsMenu/index.js +2 -2
  15. package/admin/src/hooks/useSettingsMenu/utils/formatLinks.js +3 -1
  16. package/admin/src/hooks/useSettingsMenu/utils/sortLinks.js +3 -1
  17. package/admin/src/index.js +1 -1
  18. package/admin/src/layouts/AppLayout/index.js +33 -0
  19. package/admin/src/pages/Admin/Onboarding/index.js +3 -1
  20. package/admin/src/pages/Admin/index.js +74 -80
  21. package/admin/src/pages/App/constants.js +1 -1
  22. package/admin/src/pages/App/index.js +122 -160
  23. package/admin/src/pages/AuthPage/index.js +4 -2
  24. package/admin/src/pages/HomePage/index.js +3 -1
  25. package/admin/src/pages/InstalledPluginsPage/index.js +3 -1
  26. package/admin/src/pages/{InternalErrorPage.js → InternalErrorPage/index.js} +4 -3
  27. package/admin/src/pages/{NotFoundPage.js → NotFoundPage/index.js} +3 -1
  28. package/admin/src/pages/ProfilePage/index.js +4 -2
  29. package/admin/src/pages/SettingsPage/components/SettingsNav/index.js +3 -3
  30. package/admin/src/pages/SettingsPage/constants.js +132 -67
  31. package/admin/src/pages/SettingsPage/index.js +36 -31
  32. package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +1 -1
  33. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/index.js +35 -69
  34. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/api.js +23 -0
  35. package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/prefixAllUrls.js +17 -0
  36. package/admin/src/pages/SettingsPage/pages/TransferTokens/EditView/index.js +1 -1
  37. package/admin/src/pages/SettingsPage/pages/Users/EditPage/index.js +1 -2
  38. package/admin/src/pages/SettingsPage/pages/Users/ListPage/DynamicTable/TableRows/index.js +1 -1
  39. package/admin/src/pages/SettingsPage/utils/createSectionsRoutes.js +11 -0
  40. package/admin/src/pages/SettingsPage/utils/getSectionsToDisplay.js +5 -0
  41. package/admin/src/pages/SettingsPage/utils/index.js +2 -0
  42. package/admin/src/pages/UseCasePage/index.js +175 -0
  43. package/admin/src/utils/checkFormValidity.js +15 -0
  44. package/admin/src/utils/createRoute.js +7 -5
  45. package/admin/src/utils/formatAPIErrors.js +3 -1
  46. package/admin/src/utils/getAttributesToDisplay.js +19 -0
  47. package/admin/src/utils/getExistingActions.js +32 -0
  48. package/admin/src/utils/getFullName.js +1 -1
  49. package/admin/src/utils/index.js +9 -0
  50. package/admin/src/utils/makeUniqueRoutes.js +6 -0
  51. package/admin/src/utils/sortLinks.js +3 -1
  52. package/admin/src/utils/uniqueAdminHash.js +9 -2
  53. package/build/{1049.9d69d231.chunk.js → 1049.f76cb14b.chunk.js} +1 -1
  54. package/build/1386.879bcd90.chunk.js +7 -0
  55. package/build/2225.c6244756.chunk.js +79 -0
  56. package/build/2379.f1641312.chunk.js +1 -0
  57. package/build/2395.46f8d0c1.chunk.js +26 -0
  58. package/build/2801.5cef5ec8.chunk.js +1 -0
  59. package/build/3483.03c24f96.chunk.js +1 -0
  60. package/build/3739.63e352f1.chunk.js +103 -0
  61. package/build/3929.5632f24d.chunk.js +114 -0
  62. package/build/448.829e1344.chunk.js +1 -0
  63. package/build/502.8ae8ef60.chunk.js +1 -0
  64. package/build/5483.6dd2e776.chunk.js +6 -0
  65. package/build/5542.2415a393.chunk.js +63 -0
  66. package/build/6691.4985ef22.chunk.js +105 -0
  67. package/build/7464.3e64a1d5.chunk.js +1 -0
  68. package/build/8276.10a3f883.chunk.js +26 -0
  69. package/build/{2747.d1442a90.chunk.js → 9806.5d5a0e8d.chunk.js} +64 -72
  70. package/build/9944.7af075a5.chunk.js +26 -0
  71. package/build/Admin-authenticatedApp.31497f74.chunk.js +79 -0
  72. package/build/Admin_InternalErrorPage.f45f2462.chunk.js +1 -0
  73. package/build/Admin_homePage.ac9dfb86.chunk.js +81 -0
  74. package/build/Admin_marketplace.c94239f6.chunk.js +55 -0
  75. package/build/Admin_pluginsPage.bbe79434.chunk.js +6 -0
  76. package/build/Admin_profilePage.192edc52.chunk.js +13 -0
  77. package/build/Admin_settingsPage.97cb9d41.chunk.js +111 -0
  78. package/build/admin-app.91898385.chunk.js +36 -0
  79. package/build/{admin-edit-roles-page.24bdf746.chunk.js → admin-edit-roles-page.6d567273.chunk.js} +1 -1
  80. package/build/admin-edit-users.acfd4128.chunk.js +10 -0
  81. package/build/{admin-users.2b3e4305.chunk.js → admin-users.00e20017.chunk.js} +2 -2
  82. package/build/{content-manager.fb0833bd.chunk.js → content-manager.b40f79c0.chunk.js} +78 -78
  83. package/build/{content-type-builder.66066281.chunk.js → content-type-builder.cd999f6e.chunk.js} +18 -18
  84. package/build/email-settings-page.d494d1eb.chunk.js +11 -0
  85. package/build/index.html +1 -1
  86. package/build/main.9dbe4579.js +2859 -0
  87. package/build/review-workflows-settings-create-view.cb08cfa2.chunk.js +1 -0
  88. package/build/review-workflows-settings-edit-view.3c7cbe63.chunk.js +1 -0
  89. package/build/review-workflows-settings-list-view.1611dc1f.chunk.js +56 -0
  90. package/build/runtime~main.d515c521.js +2 -0
  91. package/build/{sso-settings-page.4dba0670.chunk.js → sso-settings-page.12b6d8ae.chunk.js} +1 -1
  92. package/build/users-advanced-settings-page.f0760eb8.chunk.js +9 -0
  93. package/build/users-email-settings-page.ff4b32f3.chunk.js +9 -0
  94. package/build/users-providers-settings-page.48de0306.chunk.js +14 -0
  95. package/build/users-roles-settings-page.9d9a1eff.chunk.js +30 -0
  96. package/build/webhook-edit-page.6cb479ff.chunk.js +33 -0
  97. package/ee/admin/hooks/index.js +4 -0
  98. package/ee/admin/hooks/useAuthProviders/index.js +50 -0
  99. package/ee/admin/hooks/useAuthProviders/reducer.js +26 -0
  100. package/ee/admin/hooks/{useLicenseLimitNotification.js → useLicenseLimitNotification/index.js} +4 -2
  101. package/ee/admin/hooks/useLicenseLimits/index.js +1 -0
  102. package/ee/admin/hooks/{useLicenseLimits.js → useLicenseLimits/useLicenseLimits.js} +1 -4
  103. package/ee/admin/pages/App/constants.js +5 -6
  104. package/ee/admin/pages/AuthPage/components/Login/index.js +4 -8
  105. package/ee/admin/pages/AuthPage/components/Providers/index.js +5 -8
  106. package/ee/admin/pages/HomePage/index.js +1 -1
  107. package/ee/admin/pages/SettingsPage/constants.js +42 -27
  108. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/CreateView/CreateView.js +1 -1
  109. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/EditView/EditView.js +1 -1
  110. package/ee/admin/pages/SettingsPage/pages/ReviewWorkflows/pages/ListView/ListView.js +1 -1
  111. package/ee/admin/pages/SettingsPage/pages/Users/ListPage/CreateAction/index.js +1 -1
  112. package/ee/admin/pages/SettingsPage/pages/Users/ListPage/index.js +1 -1
  113. package/package.json +8 -8
  114. package/admin/src/components/AuthenticatedApp.js +0 -229
  115. package/admin/src/pages/UseCasePage.js +0 -174
  116. package/build/1504.eff012f7.chunk.js +0 -95
  117. package/build/2166.c837469a.chunk.js +0 -1
  118. package/build/2225.33287e1b.chunk.js +0 -79
  119. package/build/2237.03792b63.chunk.js +0 -114
  120. package/build/2379.401f56f3.chunk.js +0 -1
  121. package/build/2395.e6a79fbb.chunk.js +0 -26
  122. package/build/2801.31393ffe.chunk.js +0 -1
  123. package/build/3483.8517171f.chunk.js +0 -1
  124. package/build/502.8dd074ff.chunk.js +0 -1
  125. package/build/5483.5bfbb00d.chunk.js +0 -6
  126. package/build/7464.592a9295.chunk.js +0 -1
  127. package/build/748.fd2e5afd.chunk.js +0 -105
  128. package/build/773.6381d62d.chunk.js +0 -18
  129. package/build/7826.399afe81.chunk.js +0 -103
  130. package/build/8261.2525d35c.chunk.js +0 -7
  131. package/build/8276.e519a707.chunk.js +0 -26
  132. package/build/8299.62b67c72.chunk.js +0 -1
  133. package/build/Admin-AuthPage.90d64342.chunk.js +0 -35
  134. package/build/Admin-AuthenticatedApp.379ac945.chunk.js +0 -24
  135. package/build/Admin-UseCasePage.1f757db5.chunk.js +0 -13
  136. package/build/Admin_GuidedTourModal.8ccf1fbc.chunk.js +0 -12
  137. package/build/Admin_InternalErrorPage.9de92c6d.chunk.js +0 -9
  138. package/build/Admin_NotFoundPage.21620424.chunk.js +0 -9
  139. package/build/Admin_Onboarding.dbfa32f6.chunk.js +0 -43
  140. package/build/Admin_homePage.2000cbe9.chunk.js +0 -86
  141. package/build/Admin_marketplace.ec80e29b.chunk.js +0 -63
  142. package/build/Admin_pluginsPage.0c6851f8.chunk.js +0 -14
  143. package/build/Admin_profilePage.78cd8495.chunk.js +0 -21
  144. package/build/Admin_settingsPage.1760c3ce.chunk.js +0 -119
  145. package/build/StrapiApp.221fac30.chunk.js +0 -5
  146. package/build/admin-edit-users.5d10d444.chunk.js +0 -10
  147. package/build/email-settings-page.2f7e35c0.chunk.js +0 -11
  148. package/build/main.ee3c1938.js +0 -2859
  149. package/build/review-workflows-settings-create-view.d24a32b9.chunk.js +0 -1
  150. package/build/review-workflows-settings-edit-view.6044b022.chunk.js +0 -1
  151. package/build/review-workflows-settings-list-view.3f0ef4bc.chunk.js +0 -56
  152. package/build/runtime~main.397ee447.js +0 -2
  153. package/build/users-advanced-settings-page.17052d72.chunk.js +0 -9
  154. package/build/users-email-settings-page.3de8ea50.chunk.js +0 -9
  155. package/build/users-providers-settings-page.0eaa916d.chunk.js +0 -14
  156. package/build/users-roles-settings-page.957ad48b.chunk.js +0 -55
  157. package/build/webhook-edit-page.665210af.chunk.js +0 -33
  158. package/ee/admin/hooks/useAuthProviders.js +0 -25
  159. /package/ee/admin/hooks/{__mocks__/useLicenseLimits.js → useLicenseLimits/__mocks__/index.js} +0 -0
@@ -4,92 +4,80 @@
4
4
  *
5
5
  */
6
6
 
7
- import * as React from 'react';
7
+ import React, { lazy, Suspense, useEffect, useMemo } from 'react';
8
8
 
9
- import { Box, Flex } from '@strapi/design-system';
10
9
  import { LoadingIndicatorPage, useStrapiApp, useTracking } from '@strapi/helper-plugin';
11
10
  import { DndProvider } from 'react-dnd';
12
11
  import { HTML5Backend } from 'react-dnd-html5-backend';
13
12
  import { useDispatch, useSelector } from 'react-redux';
14
13
  import { Route, Switch } from 'react-router-dom';
15
14
 
15
+ import GuidedTourModal from '../../components/GuidedTour/Modal';
16
16
  import LeftMenu from '../../components/LeftMenu';
17
- import useConfigurations from '../../hooks/useConfigurations';
18
- import useMenu from '../../hooks/useMenu';
19
- import { createRoute } from '../../utils/createRoute';
17
+ import { useConfigurations, useMenu } from '../../hooks';
18
+ import AppLayout from '../../layouts/AppLayout';
19
+ import { createRoute } from '../../utils';
20
20
  import { SET_APP_RUNTIME_STATUS } from '../App/constants';
21
21
 
22
- const CM = React.lazy(() =>
23
- import(/* webpackChunkName: "content-manager" */ '../../content-manager/pages/App').then(
24
- (module) => ({ default: module.ContentManger })
25
- )
26
- );
27
- const GuidedTourModal = React.lazy(() =>
28
- import(/* webpackChunkName: "Admin_GuidedTourModal" */ '../../components/GuidedTour/Modal').then(
29
- (module) => ({ default: module.GuidedTourModal })
30
- )
31
- );
32
- const HomePage = React.lazy(() =>
33
- import(/* webpackChunkName: "Admin_homePage" */ '../HomePage').then((module) => ({
34
- default: module.HomePage,
35
- }))
22
+ import Onboarding from './Onboarding';
23
+
24
+ const CM = lazy(() =>
25
+ import(/* webpackChunkName: "content-manager" */ '../../content-manager/pages/App')
36
26
  );
37
- const InstalledPluginsPage = React.lazy(() =>
38
- import(/* webpackChunkName: "Admin_pluginsPage" */ '../InstalledPluginsPage').then((module) => ({
39
- default: module.PluginsPage,
40
- }))
27
+ const HomePage = lazy(() => import(/* webpackChunkName: "Admin_homePage" */ '../HomePage'));
28
+ const InstalledPluginsPage = lazy(() =>
29
+ import(/* webpackChunkName: "Admin_pluginsPage" */ '../InstalledPluginsPage')
41
30
  );
42
- const MarketplacePage = React.lazy(() =>
31
+ const MarketplacePage = lazy(() =>
43
32
  import(/* webpackChunkName: "Admin_marketplace" */ '../MarketplacePage')
44
33
  );
45
- const Onboarding = React.lazy(() =>
46
- import(/* webpackChunkName: "Admin_Onboarding" */ './Onboarding').then((module) => ({
47
- default: module.Onboarding,
48
- }))
34
+ const NotFoundPage = lazy(() =>
35
+ import(/* webpackChunkName: "Admin_NotFoundPage" */ '../NotFoundPage')
49
36
  );
50
- const ProfilePage = React.lazy(() =>
51
- import(/* webpackChunkName: "Admin_profilePage" */ '../ProfilePage').then((module) => ({
52
- default: module.ProfilePage,
53
- }))
37
+ const InternalErrorPage = lazy(() =>
38
+ import(/* webpackChunkName: "Admin_InternalErrorPage" */ '../InternalErrorPage')
39
+ );
40
+
41
+ const ProfilePage = lazy(() =>
42
+ import(/* webpackChunkName: "Admin_profilePage" */ '../ProfilePage')
54
43
  );
55
- const SettingsPage = React.lazy(() =>
56
- import(/* webpackChunkName: "Admin_settingsPage" */ '../SettingsPage').then((module) => ({
57
- default: module.SettingsPage,
58
- }))
44
+ const SettingsPage = lazy(() =>
45
+ import(/* webpackChunkName: "Admin_settingsPage" */ '../SettingsPage')
59
46
  );
60
47
 
61
- export const Admin = () => {
62
- const { isLoading, generalSectionLinks, pluginsSectionLinks } = useMenu();
63
- const { menu } = useStrapiApp();
64
- const { showTutorials } = useConfigurations();
48
+ // Simple hook easier for testing
49
+ /**
50
+ * TODO: remove this, it's bad.
51
+ */
52
+ const useTrackUsage = () => {
65
53
  const { trackUsage } = useTracking();
66
54
  const dispatch = useDispatch();
67
55
  const appStatus = useSelector((state) => state.admin_app.status);
68
56
 
69
- React.useEffect(() => {
57
+ useEffect(() => {
70
58
  // Make sure the event is only send once after accessing the admin panel
71
59
  // and not at runtime for example when regenerating the permissions with the ctb
72
60
  // or with i18n
73
61
  if (appStatus === 'init') {
74
62
  trackUsage('didAccessAuthenticatedAdministration');
63
+
75
64
  dispatch({ type: SET_APP_RUNTIME_STATUS });
76
65
  }
77
- }, [appStatus, dispatch, trackUsage]);
78
-
79
- const routes = menu
80
- .filter((link) => link.Component)
66
+ // eslint-disable-next-line react-hooks/exhaustive-deps
67
+ }, [appStatus]);
68
+ };
81
69
 
82
- /**
83
- * `Component` is an async function, which is passed as property of the
84
- * addMenuLink() API during the plugin registration step.
85
- *
86
- * Because of that we can't just render <Route component={Component} />,
87
- * but have to await the function.
88
- *
89
- * This isn't a good React pattern and should be reconsidered.
90
- */
70
+ const Admin = () => {
71
+ useTrackUsage();
72
+ const { isLoading, generalSectionLinks, pluginsSectionLinks } = useMenu();
73
+ const { menu } = useStrapiApp();
74
+ const { showTutorials } = useConfigurations();
91
75
 
92
- .map(({ to, Component, exact }) => createRoute(Component, to, exact));
76
+ const routes = useMemo(() => {
77
+ return menu
78
+ .filter((link) => link.Component)
79
+ .map(({ to, Component, exact }) => createRoute(Component, to, exact));
80
+ }, [menu]);
93
81
 
94
82
  if (isLoading) {
95
83
  return <LoadingIndicatorPage />;
@@ -97,34 +85,40 @@ export const Admin = () => {
97
85
 
98
86
  return (
99
87
  <DndProvider backend={HTML5Backend}>
100
- <Flex alignItems="stretch">
101
- <LeftMenu
102
- generalSectionLinks={generalSectionLinks}
103
- pluginsSectionLinks={pluginsSectionLinks}
104
- />
105
-
106
- <Box flex="1">
107
- <React.Suspense fallback={<LoadingIndicatorPage />}>
108
- <Switch>
109
- <Route path="/" component={HomePage} exact />
110
- <Route path="/me" component={ProfilePage} exact />
111
- <Route path="/content-manager" component={CM} />
112
- {routes}
113
- <Route path="/settings/:settingId" component={SettingsPage} />
114
- <Route path="/settings" component={SettingsPage} exact />
115
- <Route path="/marketplace" component={MarketplacePage} />
116
- <Route path="/list-plugins" component={InstalledPluginsPage} exact />
117
- </Switch>
118
- </React.Suspense>
119
- </Box>
120
-
121
- {/* TODO: we should move the logic to determine whether the guided tour is displayed
122
- or not out of the component, to make the code-splitting more effective
123
- */}
88
+ <AppLayout
89
+ sideNav={
90
+ <LeftMenu
91
+ generalSectionLinks={generalSectionLinks}
92
+ pluginsSectionLinks={pluginsSectionLinks}
93
+ />
94
+ }
95
+ >
96
+ <Suspense fallback={<LoadingIndicatorPage />}>
97
+ <Switch>
98
+ <Route path="/" component={HomePage} exact />
99
+ <Route path="/me" component={ProfilePage} exact />
100
+ <Route path="/content-manager" component={CM} />
101
+ {routes}
102
+ <Route path="/settings/:settingId" component={SettingsPage} />
103
+ <Route path="/settings" component={SettingsPage} exact />
104
+ <Route path="/marketplace">
105
+ <MarketplacePage />
106
+ </Route>
107
+ <Route path="/list-plugins" exact>
108
+ <InstalledPluginsPage />
109
+ </Route>
110
+ <Route path="/404" component={NotFoundPage} />
111
+ <Route path="/500" component={InternalErrorPage} />
112
+ <Route path="" component={NotFoundPage} />
113
+ </Switch>
114
+ </Suspense>
124
115
  <GuidedTourModal />
125
116
 
126
117
  {showTutorials && <Onboarding />}
127
- </Flex>
118
+ </AppLayout>
128
119
  </DndProvider>
129
120
  );
130
121
  };
122
+
123
+ export default Admin;
124
+ export { useTrackUsage };
@@ -1,4 +1,4 @@
1
1
  export const SET_APP_RUNTIME_STATUS = 'StrapiAdmin/APP/SET_APP_RUNTIME_STATUS';
2
2
  export const SET_ADMIN_PERMISSIONS = 'StrapiAdmin/App/SET_ADMIN_PERMISSIONS';
3
3
 
4
- export const AUTH_ROUTES_CE = [];
4
+ export const ROUTES_CE = [];
@@ -1,4 +1,10 @@
1
- import * as React from 'react';
1
+ /**
2
+ *
3
+ * App.js
4
+ *
5
+ */
6
+
7
+ import React, { lazy, Suspense, useEffect, useMemo, useState } from 'react';
2
8
 
3
9
  import { SkipToContent } from '@strapi/design-system';
4
10
  import {
@@ -6,57 +12,31 @@ import {
6
12
  LoadingIndicatorPage,
7
13
  prefixFileUrlWithBackendUrl,
8
14
  TrackingProvider,
15
+ useAppInfo,
9
16
  useFetchClient,
17
+ useNotification,
10
18
  } from '@strapi/helper-plugin';
11
19
  import merge from 'lodash/merge';
12
20
  import { useIntl } from 'react-intl';
13
- import { useQueries } from 'react-query';
14
21
  import { useDispatch } from 'react-redux';
15
22
  import { Route, Switch } from 'react-router-dom';
16
23
 
17
24
  import PrivateRoute from '../../components/PrivateRoute';
18
25
  import { ADMIN_PERMISSIONS_CE } from '../../constants';
19
- import useConfigurations from '../../hooks/useConfigurations';
26
+ import { useConfigurations } from '../../hooks';
20
27
  import { useEnterprise } from '../../hooks/useEnterprise';
28
+ import { createRoute, makeUniqueRoutes } from '../../utils';
29
+ import AuthPage from '../AuthPage';
30
+ import NotFoundPage from '../NotFoundPage';
31
+ import UseCasePage from '../UseCasePage';
21
32
 
22
- import { AUTH_ROUTES_CE, SET_ADMIN_PERMISSIONS } from './constants';
23
-
24
- const AuthPage = React.lazy(() =>
25
- import(/* webpackChunkName: "Admin-AuthPage" */ '../AuthPage').then((module) => ({
26
- default: module.AuthPage,
27
- }))
28
- );
29
-
30
- const AuthenticatedApp = React.lazy(() =>
31
- import(/* webpackChunkName: "Admin-AuthenticatedApp" */ '../../components/AuthenticatedApp').then(
32
- (module) => ({ default: module.AuthenticatedApp })
33
- )
34
- );
33
+ import { ROUTES_CE, SET_ADMIN_PERMISSIONS } from './constants';
35
34
 
36
- const UseCasePage = React.lazy(() =>
37
- import(/* webpackChunkName: "Admin-UseCasePage" */ '../UseCasePage').then((module) => ({
38
- default: module.UseCasePage,
39
- }))
35
+ const AuthenticatedApp = lazy(() =>
36
+ import(/* webpackChunkName: "Admin-authenticatedApp" */ '../../components/AuthenticatedApp')
40
37
  );
41
38
 
42
- const NotFoundPage = React.lazy(() =>
43
- import(/* webpackChunkName: "Admin_NotFoundPage" */ '../NotFoundPage').then((module) => ({
44
- default: module.NotFoundPage,
45
- }))
46
- );
47
-
48
- const InternalErrorPage = React.lazy(() =>
49
- import(/* webpackChunkName: "Admin_InternalErrorPage" */ '../InternalErrorPage').then(
50
- (module) => ({ default: module.InternalErrorPage })
51
- )
52
- );
53
-
54
- export function App() {
55
- const { updateProjectSettings } = useConfigurations();
56
- const { formatMessage } = useIntl();
57
- const dispatch = useDispatch();
58
- const { get, post } = useFetchClient();
59
-
39
+ function App() {
60
40
  const adminPermissions = useEnterprise(
61
41
  ADMIN_PERMISSIONS_CE,
62
42
  async () => (await import('../../../../ee/admin/constants')).ADMIN_PERMISSIONS_EE,
@@ -69,173 +49,155 @@ export function App() {
69
49
  defaultValue: ADMIN_PERMISSIONS_CE,
70
50
  }
71
51
  );
72
-
73
- // Load authentication routes for CE and EE (SSO)
74
- const authRoutes = useEnterprise(
75
- AUTH_ROUTES_CE,
76
- async () => (await import('../../../../ee/admin/pages/App/constants')).AUTH_ROUTES_EE,
52
+ const routes = useEnterprise(
53
+ ROUTES_CE,
54
+ async () => (await import('../../../../ee/admin/pages/App/constants')).ROUTES_EE,
77
55
  {
78
56
  defaultValue: [],
79
57
  }
80
58
  );
81
-
82
- // TODO: this should be moved to redux
83
- const [{ hasAdmin, uuid }, setState] = React.useState({
59
+ const toggleNotification = useNotification();
60
+ const { updateProjectSettings } = useConfigurations();
61
+ const { formatMessage } = useIntl();
62
+ const [{ isLoading, hasAdmin, uuid, deviceId }, setState] = useState({
63
+ isLoading: true,
84
64
  hasAdmin: false,
85
- uuid: undefined,
86
65
  });
66
+ const dispatch = useDispatch();
67
+ const appInfo = useAppInfo();
68
+ const { get, post } = useFetchClient();
69
+
70
+ const authRoutes = useMemo(() => {
71
+ return makeUniqueRoutes(
72
+ routes.map(({ to, Component, exact }) => createRoute(Component, to, exact))
73
+ );
74
+ }, [routes]);
75
+
76
+ const [telemetryProperties, setTelemetryProperties] = useState(null);
87
77
 
88
- // Store permissions in redux
89
- React.useEffect(() => {
78
+ useEffect(() => {
90
79
  dispatch({ type: SET_ADMIN_PERMISSIONS, payload: adminPermissions });
91
80
  }, [adminPermissions, dispatch]);
92
81
 
93
- const [
94
- { data: token, error: errorRenewToken },
95
- { data: initData, isLoading: isLoadingInit },
96
- { data: telemetryProperties },
97
- ] = useQueries([
98
- {
99
- queryKey: 'renew-token',
100
- async queryFn() {
82
+ useEffect(() => {
83
+ const currentToken = auth.getToken();
84
+
85
+ const renewToken = async () => {
86
+ try {
101
87
  const {
102
88
  data: {
103
89
  data: { token },
104
90
  },
105
- } = await post('/admin/renew-token', { token: auth.getToken() });
106
-
107
- return token;
108
- },
109
-
110
- enabled: !!auth.getToken(),
111
- },
91
+ } = await post('/admin/renew-token', { token: currentToken });
92
+ auth.updateToken(token);
93
+ } catch (err) {
94
+ // Refresh app
95
+ auth.clearAppStorage();
96
+ window.location.reload();
97
+ }
98
+ };
99
+
100
+ if (currentToken) {
101
+ renewToken();
102
+ }
103
+ }, [post]);
112
104
 
113
- {
114
- queryKey: 'init',
115
- async queryFn() {
105
+ useEffect(() => {
106
+ const getData = async () => {
107
+ try {
116
108
  const {
117
- data: { data },
109
+ data: {
110
+ data: { hasAdmin, uuid, menuLogo, authLogo },
111
+ },
118
112
  } = await get(`/admin/init`);
119
113
 
120
- return data;
121
- },
122
- },
123
-
124
- {
125
- queryKey: 'telemetry-properties',
126
- async queryFn() {
127
- const {
128
- data: { data },
129
- } = await get(`/admin/telemetry-properties`, {
130
- // NOTE: needed because the interceptors of the fetchClient redirect to /login when receive a
131
- // 401 and it would end up in an infinite loop when the user doesn't have a session.
132
- validateStatus: (status) => status < 500,
114
+ updateProjectSettings({
115
+ menuLogo: prefixFileUrlWithBackendUrl(menuLogo),
116
+ authLogo: prefixFileUrlWithBackendUrl(authLogo),
133
117
  });
134
118
 
135
- return data;
136
- },
119
+ if (uuid) {
120
+ const {
121
+ data: { data: properties },
122
+ } = await get(`/admin/telemetry-properties`, {
123
+ // NOTE: needed because the interceptors of the fetchClient redirect to /login when receive a 401 and it would end up in an infinite loop when the user doesn't have a session.
124
+ validateStatus: (status) => status < 500,
125
+ });
126
+
127
+ setTelemetryProperties(properties);
128
+
129
+ try {
130
+ const event = 'didInitializeAdministration';
131
+ await post(
132
+ 'https://analytics.strapi.io/api/v2/track',
133
+ {
134
+ // This event is anonymous
135
+ event,
136
+ userId: '',
137
+ deviceId,
138
+ eventPropeties: {},
139
+ userProperties: { environment: appInfo.currentEnvironment },
140
+ groupProperties: { ...properties, projectId: uuid },
141
+ },
142
+ {
143
+ headers: {
144
+ 'X-Strapi-Event': event,
145
+ },
146
+ }
147
+ );
148
+ } catch (e) {
149
+ // Silent.
150
+ }
151
+ }
152
+
153
+ setState({ isLoading: false, hasAdmin, uuid, deviceId });
154
+ } catch (err) {
155
+ toggleNotification({
156
+ type: 'warning',
157
+ message: { id: 'app.containers.App.notification.error.init' },
158
+ });
159
+ }
160
+ };
137
161
 
138
- enabled: !!auth.getToken(),
139
- },
140
- ]);
141
-
142
- React.useEffect(() => {
143
- // If the renew token could not be fetched, logout the user
144
- if (errorRenewToken) {
145
- auth.clearAppStorage();
146
- window.location.reload();
147
- } else if (token) {
148
- auth.updateToken(token);
149
- }
150
- }, [errorRenewToken, token]);
151
-
152
- // Store the fetched project settings (e.g. logos)
153
- // TODO: this should be moved to redux
154
- React.useEffect(() => {
155
- if (!isLoadingInit && initData) {
156
- updateProjectSettings({
157
- menuLogo: prefixFileUrlWithBackendUrl(initData.menuLogo),
158
- authLogo: prefixFileUrlWithBackendUrl(initData.authLogo),
159
- });
160
-
161
- // TODO: this should be stored in redux
162
- setState((prev) => ({
163
- ...prev,
164
- hasAdmin: initData.hasAdmin,
165
- uuid: initData.uuid,
166
- }));
167
- }
168
- }, [initData, isLoadingInit, updateProjectSettings]);
169
-
170
- // We can't use useTracking here, because `App` is not wrapped in the tracking provider
171
- // context, which we can't do because the context values contain data that can only be
172
- // accessed when a user is logged in.
173
- // This should not use `useFetchClient`, because it does not communicate to the admin API.
174
- React.useEffect(() => {
175
- async function trackInitEvent() {
176
- await fetch('https://analytics.strapi.io/api/v2/track', {
177
- body: JSON.stringify({
178
- event: 'didInitializeAdministration',
179
- // This event is anonymous
180
- userId: '',
181
- eventPropeties: {},
182
- userProperties: {},
183
- groupProperties: { ...telemetryProperties, projectId: uuid },
184
- }),
185
-
186
- headers: {
187
- 'Content-Type': 'application/json',
188
- 'X-Strapi-Event': 'didInitializeAdministration',
189
- },
190
-
191
- method: 'POST',
192
- });
193
- }
162
+ getData();
163
+ // eslint-disable-next-line react-hooks/exhaustive-deps
164
+ }, [toggleNotification, updateProjectSettings]);
194
165
 
195
- if (uuid) {
196
- trackInitEvent();
197
- }
198
- }, [telemetryProperties, uuid]);
166
+ const setHasAdmin = (hasAdmin) => setState((prev) => ({ ...prev, hasAdmin }));
199
167
 
200
- const trackingContext = React.useMemo(
168
+ const trackingInfo = useMemo(
201
169
  () => ({
202
170
  uuid,
203
171
  telemetryProperties,
172
+ deviceId,
204
173
  }),
205
- [uuid, telemetryProperties]
174
+ [uuid, telemetryProperties, deviceId]
206
175
  );
207
176
 
208
- if (isLoadingInit) {
177
+ if (isLoading) {
209
178
  return <LoadingIndicatorPage />;
210
179
  }
211
180
 
212
181
  return (
213
- <React.Suspense fallback={<LoadingIndicatorPage />}>
182
+ <Suspense fallback={<LoadingIndicatorPage />}>
214
183
  <SkipToContent>{formatMessage({ id: 'skipToContent' })}</SkipToContent>
215
- <TrackingProvider value={trackingContext}>
184
+ <TrackingProvider value={trackingInfo}>
216
185
  <Switch>
217
- {authRoutes.map(({ path, component }) => (
218
- <Route key={path} path={path} component={component} exact />
219
- ))}
220
-
186
+ {authRoutes}
221
187
  <Route
222
188
  path="/auth/:authType"
223
189
  render={(routerProps) => (
224
- <AuthPage
225
- {...routerProps}
226
- setHasAdmin={(hasAdmin) => setState((prev) => ({ ...prev, hasAdmin }))}
227
- hasAdmin={hasAdmin}
228
- />
190
+ <AuthPage {...routerProps} setHasAdmin={setHasAdmin} hasAdmin={hasAdmin} />
229
191
  )}
230
192
  exact
231
193
  />
232
194
  <PrivateRoute path="/usecase" component={UseCasePage} />
233
195
  <PrivateRoute path="/" component={AuthenticatedApp} />
234
- <Route path="/404" component={NotFoundPage} />
235
- <Route path="/500" component={InternalErrorPage} />
236
196
  <Route path="" component={NotFoundPage} />
237
197
  </Switch>
238
198
  </TrackingProvider>
239
- </React.Suspense>
199
+ </Suspense>
240
200
  );
241
201
  }
202
+
203
+ export default App;
@@ -11,14 +11,14 @@ import { Redirect, useHistory, useRouteMatch } from 'react-router-dom';
11
11
  import persistStateToLocaleStorage from '../../components/GuidedTour/utils/persistStateToLocaleStorage';
12
12
  import useLocalesProvider from '../../components/LocalesProvider/useLocalesProvider';
13
13
  import { useEnterprise } from '../../hooks/useEnterprise';
14
- import { formatAPIErrors } from '../../utils/formatAPIErrors';
14
+ import formatAPIErrors from '../../utils/formatAPIErrors';
15
15
 
16
16
  import { LoginCE } from './components/Login';
17
17
  import { FORMS } from './constants';
18
18
  import init from './init';
19
19
  import { initialState, reducer } from './reducer';
20
20
 
21
- export const AuthPage = ({ hasAdmin, setHasAdmin }) => {
21
+ const AuthPage = ({ hasAdmin, setHasAdmin }) => {
22
22
  const {
23
23
  push,
24
24
  location: { search },
@@ -315,3 +315,5 @@ AuthPage.propTypes = {
315
315
  hasAdmin: PropTypes.bool,
316
316
  setHasAdmin: PropTypes.func.isRequired,
317
317
  };
318
+
319
+ export default AuthPage;
@@ -89,7 +89,7 @@ export const HomePageCE = () => {
89
89
  );
90
90
  };
91
91
 
92
- export function HomePage() {
92
+ function HomePageSwitch() {
93
93
  const HomePage = useEnterprise(
94
94
  HomePageCE,
95
95
  // eslint-disable-next-line import/no-cycle
@@ -103,3 +103,5 @@ export function HomePage() {
103
103
 
104
104
  return <HomePage />;
105
105
  }
106
+
107
+ export default HomePageSwitch;
@@ -9,7 +9,7 @@ import { selectAdminPermissions } from '../App/selectors';
9
9
 
10
10
  import Plugins from './Plugins';
11
11
 
12
- export const PluginsPage = () => {
12
+ const InstalledPluginsPage = () => {
13
13
  const { formatMessage } = useIntl();
14
14
  const permissions = useSelector(selectAdminPermissions);
15
15
 
@@ -25,3 +25,5 @@ export const PluginsPage = () => {
25
25
  </CheckPagePermissions>
26
26
  );
27
27
  };
28
+
29
+ export default InstalledPluginsPage;
@@ -4,16 +4,15 @@
4
4
  * This is the page we show when the user gets a 500 error
5
5
  *
6
6
  */
7
- import * as React from 'react';
7
+ import React from 'react';
8
8
 
9
9
  import { ContentLayout, EmptyStateLayout, HeaderLayout, Main } from '@strapi/design-system';
10
10
  import { LinkButton, useFocusWhenNavigate } from '@strapi/helper-plugin';
11
11
  import { ArrowRight, EmptyPictures } from '@strapi/icons';
12
12
  import { useIntl } from 'react-intl';
13
13
 
14
- export const InternalErrorPage = () => {
14
+ const InternalErrorPage = () => {
15
15
  const { formatMessage } = useIntl();
16
-
17
16
  useFocusWhenNavigate();
18
17
 
19
18
  return (
@@ -47,3 +46,5 @@ export const InternalErrorPage = () => {
47
46
  </Main>
48
47
  );
49
48
  };
49
+
50
+ export default InternalErrorPage;
@@ -11,7 +11,7 @@ import { LinkButton, useFocusWhenNavigate } from '@strapi/helper-plugin';
11
11
  import { ArrowRight, EmptyPictures } from '@strapi/icons';
12
12
  import { useIntl } from 'react-intl';
13
13
 
14
- export const NotFoundPage = () => {
14
+ const NoContentType = () => {
15
15
  const { formatMessage } = useIntl();
16
16
  useFocusWhenNavigate();
17
17
 
@@ -46,3 +46,5 @@ export const NotFoundPage = () => {
46
46
  </Main>
47
47
  );
48
48
  };
49
+
50
+ export default NoContentType;