mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 11:54:10 +00:00 
			
		
		
		
	Merge pull request #17844 from strapi/revert-17685-fix/code-splitting
Revert "Fix: Use sync over async components in admin panel APIs"
This commit is contained in:
		
						commit
						ba1b99b408
					
				@ -1,4 +1,4 @@
 | 
				
			|||||||
import * as React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { darkTheme, lightTheme } from '@strapi/design-system';
 | 
					import { darkTheme, lightTheme } from '@strapi/design-system';
 | 
				
			||||||
import invariant from 'invariant';
 | 
					import invariant from 'invariant';
 | 
				
			||||||
@ -114,30 +114,14 @@ class StrapiApp {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
    invariant(
 | 
					    invariant(
 | 
				
			||||||
      link.Component && typeof link.Component === 'function',
 | 
					      link.Component && typeof link.Component === 'function',
 | 
				
			||||||
      `link.Component must be a function returning a Promise. Please use: \`Component: () => import(path)\` instead.`
 | 
					      `link.Component should be a valid React Component`
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    invariant(
 | 
					    invariant(
 | 
				
			||||||
      link.icon && typeof link.icon === 'function',
 | 
					      link.icon && typeof link.icon === 'function',
 | 
				
			||||||
      `link.Icon should be a valid React Component`
 | 
					      `link.Icon should be a valid React Component`
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (
 | 
					    this.menu.push(link);
 | 
				
			||||||
      link.Component &&
 | 
					 | 
				
			||||||
      typeof link.Component === 'function' &&
 | 
					 | 
				
			||||||
      link.Component[Symbol.toStringTag] === 'AsyncFunction'
 | 
					 | 
				
			||||||
    ) {
 | 
					 | 
				
			||||||
      console.warn(`
 | 
					 | 
				
			||||||
        [deprecated] addMenuLink() was called with an async Component from the plugin "${link.intlLabel.Internationalization}". This will be removed
 | 
					 | 
				
			||||||
        in the future. Please use: \`Component: () => import(path)\` instead.
 | 
					 | 
				
			||||||
      `);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.menu.push({
 | 
					 | 
				
			||||||
      ...link,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // React.lazy can be removed once we migrate to react-router@6, because the <Route /> component can handle it natively
 | 
					 | 
				
			||||||
      Component: React.lazy(link.Component),
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  addMiddlewares = (middlewares) => {
 | 
					  addMiddlewares = (middlewares) => {
 | 
				
			||||||
@ -165,26 +149,10 @@ class StrapiApp {
 | 
				
			|||||||
    invariant(link.to, `link.to should be defined for ${stringifiedLink}`);
 | 
					    invariant(link.to, `link.to should be defined for ${stringifiedLink}`);
 | 
				
			||||||
    invariant(
 | 
					    invariant(
 | 
				
			||||||
      link.Component && typeof link.Component === 'function',
 | 
					      link.Component && typeof link.Component === 'function',
 | 
				
			||||||
      `link.Component must be a function returning a Promise. Please use: \`Component: () => import(path)\` instead.`
 | 
					      `link.Component should be a valid React Component`
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (
 | 
					    this.settings[sectionId].links.push(link);
 | 
				
			||||||
      link.Component &&
 | 
					 | 
				
			||||||
      typeof link.Component === 'function' &&
 | 
					 | 
				
			||||||
      link.Component[Symbol.toStringTag] === 'AsyncFunction'
 | 
					 | 
				
			||||||
    ) {
 | 
					 | 
				
			||||||
      console.warn(`
 | 
					 | 
				
			||||||
        [deprecated] addSettingsLink() was called with an async Component from the plugin: "${link.intlLabel.Internationalization}". This will be removed
 | 
					 | 
				
			||||||
        in the future. Please use: \`Component: () => import(path)\` instead.
 | 
					 | 
				
			||||||
      `);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.settings[sectionId].links.push({
 | 
					 | 
				
			||||||
      ...link,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // React.lazy can be removed once we migrate to react-router@6, because the <Route /> component can handle it natively
 | 
					 | 
				
			||||||
      Component: React.lazy(link.Component),
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  addSettingsLinks = (sectionId, links) => {
 | 
					  addSettingsLinks = (sectionId, links) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -111,8 +111,7 @@ Providers.propTypes = {
 | 
				
			|||||||
        defaultMessage: PropTypes.string.isRequired,
 | 
					        defaultMessage: PropTypes.string.isRequired,
 | 
				
			||||||
      }).isRequired,
 | 
					      }).isRequired,
 | 
				
			||||||
      permissions: PropTypes.array,
 | 
					      permissions: PropTypes.array,
 | 
				
			||||||
      // React.lazy loadable
 | 
					      Component: PropTypes.func,
 | 
				
			||||||
      Component: PropTypes.object,
 | 
					 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  ).isRequired,
 | 
					  ).isRequired,
 | 
				
			||||||
  menuLogo: PropTypes.oneOfType([PropTypes.string, PropTypes.any]).isRequired,
 | 
					  menuLogo: PropTypes.oneOfType([PropTypes.string, PropTypes.any]).isRequired,
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@ import { Route, Switch } from 'react-router-dom';
 | 
				
			|||||||
import LeftMenu from '../../components/LeftMenu';
 | 
					import LeftMenu from '../../components/LeftMenu';
 | 
				
			||||||
import useConfigurations from '../../hooks/useConfigurations';
 | 
					import useConfigurations from '../../hooks/useConfigurations';
 | 
				
			||||||
import useMenu from '../../hooks/useMenu';
 | 
					import useMenu from '../../hooks/useMenu';
 | 
				
			||||||
 | 
					import { createRoute } from '../../utils/createRoute';
 | 
				
			||||||
import { SET_APP_RUNTIME_STATUS } from '../App/constants';
 | 
					import { SET_APP_RUNTIME_STATUS } from '../App/constants';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const CM = React.lazy(() =>
 | 
					const CM = React.lazy(() =>
 | 
				
			||||||
@ -75,6 +76,25 @@ export const Admin = () => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }, [appStatus, dispatch, trackUsage]);
 | 
					  }, [appStatus, dispatch, trackUsage]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const routes = menu
 | 
				
			||||||
 | 
					    .filter((link) => link.Component)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * `Component` is an async function, which is passed as property of the
 | 
				
			||||||
 | 
					     * addMenuLink() API during the plugin registration step.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Because of that we can't just render <Route component={Component} />,
 | 
				
			||||||
 | 
					     * but have to await the function.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This isn't a good React pattern and should be reconsidered.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .map(({ to, Component, exact }) => createRoute(Component, to, exact));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (isLoading) {
 | 
				
			||||||
 | 
					    return <LoadingIndicatorPage />;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <DndProvider backend={HTML5Backend}>
 | 
					    <DndProvider backend={HTML5Backend}>
 | 
				
			||||||
      <Flex alignItems="stretch">
 | 
					      <Flex alignItems="stretch">
 | 
				
			||||||
@ -84,31 +104,18 @@ export const Admin = () => {
 | 
				
			|||||||
        />
 | 
					        />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <Box flex="1">
 | 
					        <Box flex="1">
 | 
				
			||||||
          {isLoading ? (
 | 
					          <React.Suspense fallback={<LoadingIndicatorPage />}>
 | 
				
			||||||
            <LoadingIndicatorPage />
 | 
					 | 
				
			||||||
          ) : (
 | 
					 | 
				
			||||||
            <Switch>
 | 
					            <Switch>
 | 
				
			||||||
              <Route path="/" component={HomePage} exact />
 | 
					              <Route path="/" component={HomePage} exact />
 | 
				
			||||||
              <Route path="/me" component={ProfilePage} exact />
 | 
					              <Route path="/me" component={ProfilePage} exact />
 | 
				
			||||||
              <Route path="/content-manager" component={CM} />
 | 
					              <Route path="/content-manager" component={CM} />
 | 
				
			||||||
              {menu.map(({ to, Component, exact }) => (
 | 
					              {routes}
 | 
				
			||||||
                <Route
 | 
					 | 
				
			||||||
                  render={() => (
 | 
					 | 
				
			||||||
                    <React.Suspense fallback={<LoadingIndicatorPage />}>
 | 
					 | 
				
			||||||
                      <Component />
 | 
					 | 
				
			||||||
                    </React.Suspense>
 | 
					 | 
				
			||||||
                  )}
 | 
					 | 
				
			||||||
                  key={to}
 | 
					 | 
				
			||||||
                  path={to}
 | 
					 | 
				
			||||||
                  exact={exact || false}
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
              ))}
 | 
					 | 
				
			||||||
              <Route path="/settings/:settingId" component={SettingsPage} />
 | 
					              <Route path="/settings/:settingId" component={SettingsPage} />
 | 
				
			||||||
              <Route path="/settings" component={SettingsPage} exact />
 | 
					              <Route path="/settings" component={SettingsPage} exact />
 | 
				
			||||||
              <Route path="/marketplace" component={MarketplacePage} />
 | 
					              <Route path="/marketplace" component={MarketplacePage} />
 | 
				
			||||||
              <Route path="/list-plugins" component={InstalledPluginsPage} exact />
 | 
					              <Route path="/list-plugins" component={InstalledPluginsPage} exact />
 | 
				
			||||||
            </Switch>
 | 
					            </Switch>
 | 
				
			||||||
          )}
 | 
					          </React.Suspense>
 | 
				
			||||||
        </Box>
 | 
					        </Box>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {/* TODO: we should move the logic to determine whether the guided tour is displayed
 | 
					        {/* TODO: we should move the logic to determine whether the guided tour is displayed
 | 
				
			||||||
 | 
				
			|||||||
@ -2,67 +2,67 @@ import * as React from 'react';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export const SETTINGS_ROUTES_CE = [
 | 
					export const SETTINGS_ROUTES_CE = [
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(/* webpackChunkName: "admin-roles-list" */ './pages/Roles/ProtectedListPage')
 | 
					      import(/* webpackChunkName: "admin-roles-list" */ './pages/Roles/ProtectedListPage')
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path: '/settings/roles',
 | 
					    path: '/settings/roles',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(/* webpackChunkName: "admin-edit-roles-page" */ './pages/Roles/CreatePage')
 | 
					      import(/* webpackChunkName: "admin-edit-roles-page" */ './pages/Roles/CreatePage')
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path: '/settings/roles/duplicate/:id',
 | 
					    path: '/settings/roles/duplicate/:id',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(/* webpackChunkName: "admin-edit-roles-page" */ './pages/Roles/CreatePage')
 | 
					      import(/* webpackChunkName: "admin-edit-roles-page" */ './pages/Roles/CreatePage')
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path: '/settings/roles/new',
 | 
					    path: '/settings/roles/new',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(/* webpackChunkName: "admin-edit-roles-page" */ './pages/Roles/ProtectedEditPage')
 | 
					      import(/* webpackChunkName: "admin-edit-roles-page" */ './pages/Roles/ProtectedEditPage')
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path: '/settings/roles/:id',
 | 
					    path: '/settings/roles/:id',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(/* webpackChunkName: "admin-users" */ './pages/Users/ProtectedListPage')
 | 
					      import(/* webpackChunkName: "admin-users" */ './pages/Users/ProtectedListPage')
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path: '/settings/users',
 | 
					    path: '/settings/users',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(/* webpackChunkName: "admin-edit-users" */ './pages/Users/ProtectedEditPage')
 | 
					      import(/* webpackChunkName: "admin-edit-users" */ './pages/Users/ProtectedEditPage')
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path: '/settings/users/:id',
 | 
					    path: '/settings/users/:id',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(/* webpackChunkName: "webhook-edit-page" */ './pages/Webhooks/ProtectedCreateView')
 | 
					      import(/* webpackChunkName: "webhook-edit-page" */ './pages/Webhooks/ProtectedCreateView')
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path: '/settings/webhooks/create',
 | 
					    path: '/settings/webhooks/create',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(/* webpackChunkName: "webhook-edit-page" */ './pages/Webhooks/ProtectedEditView')
 | 
					      import(/* webpackChunkName: "webhook-edit-page" */ './pages/Webhooks/ProtectedEditView')
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path: '/settings/webhooks/:id',
 | 
					    path: '/settings/webhooks/:id',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(/* webpackChunkName: "webhook-list-page" */ './pages/Webhooks/ProtectedListView')
 | 
					      import(/* webpackChunkName: "webhook-list-page" */ './pages/Webhooks/ProtectedListView')
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path: '/settings/webhooks',
 | 
					    path: '/settings/webhooks',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(/* webpackChunkName: "api-tokens-list-page" */ './pages/ApiTokens/ProtectedListView')
 | 
					      import(/* webpackChunkName: "api-tokens-list-page" */ './pages/ApiTokens/ProtectedListView')
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path: '/settings/api-tokens',
 | 
					    path: '/settings/api-tokens',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(
 | 
					      import(
 | 
				
			||||||
        /* webpackChunkName: "api-tokens-create-page" */ './pages/ApiTokens/ProtectedCreateView'
 | 
					        /* webpackChunkName: "api-tokens-create-page" */ './pages/ApiTokens/ProtectedCreateView'
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
@ -70,13 +70,13 @@ export const SETTINGS_ROUTES_CE = [
 | 
				
			|||||||
    path: '/settings/api-tokens/create',
 | 
					    path: '/settings/api-tokens/create',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(/* webpackChunkName: "api-tokens-edit-page" */ './pages/ApiTokens/ProtectedEditView')
 | 
					      import(/* webpackChunkName: "api-tokens-edit-page" */ './pages/ApiTokens/ProtectedEditView')
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path: '/settings/api-tokens/:id',
 | 
					    path: '/settings/api-tokens/:id',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(
 | 
					      import(
 | 
				
			||||||
        /* webpackChunkName: "transfer-tokens-create-page" */ './pages/TransferTokens/ProtectedCreateView'
 | 
					        /* webpackChunkName: "transfer-tokens-create-page" */ './pages/TransferTokens/ProtectedCreateView'
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
@ -84,7 +84,7 @@ export const SETTINGS_ROUTES_CE = [
 | 
				
			|||||||
    path: '/settings/transfer-tokens/create',
 | 
					    path: '/settings/transfer-tokens/create',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(
 | 
					      import(
 | 
				
			||||||
        /* webpackChunkName: "transfer-tokens-list-page" */ './pages/TransferTokens/ProtectedListView'
 | 
					        /* webpackChunkName: "transfer-tokens-list-page" */ './pages/TransferTokens/ProtectedListView'
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
@ -92,7 +92,7 @@ export const SETTINGS_ROUTES_CE = [
 | 
				
			|||||||
    path: '/settings/transfer-tokens',
 | 
					    path: '/settings/transfer-tokens',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    Component: React.lazy(() =>
 | 
					    component: React.lazy(() =>
 | 
				
			||||||
      import(
 | 
					      import(
 | 
				
			||||||
        /* webpackChunkName: "transfer-tokens-edit-page" */ './pages/TransferTokens/ProtectedEditView'
 | 
					        /* webpackChunkName: "transfer-tokens-edit-page" */ './pages/TransferTokens/ProtectedEditView'
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@ import { Redirect, Route, Switch, useParams } from 'react-router-dom';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { useSettingsMenu } from '../../hooks';
 | 
					import { useSettingsMenu } from '../../hooks';
 | 
				
			||||||
import { useEnterprise } from '../../hooks/useEnterprise';
 | 
					import { useEnterprise } from '../../hooks/useEnterprise';
 | 
				
			||||||
 | 
					import { createRoute } from '../../utils/createRoute';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import SettingsNav from './components/SettingsNav';
 | 
					import SettingsNav from './components/SettingsNav';
 | 
				
			||||||
import { SETTINGS_ROUTES_CE } from './constants';
 | 
					import { SETTINGS_ROUTES_CE } from './constants';
 | 
				
			||||||
@ -30,6 +31,26 @@ export function SettingsPage() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * `Component` is an async function, which is passed as property of the
 | 
				
			||||||
 | 
					   * addSettingsLink() API during the plugin bootstrap step.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * Because of that we can't just render <Route component={Component} />,
 | 
				
			||||||
 | 
					   * but have to await the function.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * This isn't a good React pattern and should be reconsidered.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const pluginSettingsRoutes = Object.values(settings).flatMap((section) =>
 | 
				
			||||||
 | 
					    section.links.map((link) => createRoute(link.Component, link.to, link.exact || false))
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Since the useSettingsMenu hook can make API calls in order to check the links permissions
 | 
				
			||||||
 | 
					  // We need to add a loading state to prevent redirecting the user while permissions are being checked
 | 
				
			||||||
 | 
					  if (isLoading) {
 | 
				
			||||||
 | 
					    return <LoadingIndicatorPage />;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!settingId) {
 | 
					  if (!settingId) {
 | 
				
			||||||
    return <Redirect to="/settings/application-infos" />;
 | 
					    return <Redirect to="/settings/application-infos" />;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -43,49 +64,15 @@ export function SettingsPage() {
 | 
				
			|||||||
        })}
 | 
					        })}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      {isLoading ? (
 | 
					 | 
				
			||||||
        <LoadingIndicatorPage />
 | 
					 | 
				
			||||||
      ) : (
 | 
					 | 
				
			||||||
      <Switch>
 | 
					      <Switch>
 | 
				
			||||||
          <Route
 | 
					        <Route path="/settings/application-infos" component={ApplicationInfosPage} exact />
 | 
				
			||||||
            path="/settings/application-infos"
 | 
					 | 
				
			||||||
            render={() => (
 | 
					 | 
				
			||||||
              <React.Suspense fallback={<LoadingIndicatorPage />}>
 | 
					 | 
				
			||||||
                <ApplicationInfosPage />
 | 
					 | 
				
			||||||
              </React.Suspense>
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
            exact
 | 
					 | 
				
			||||||
          />
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
          {routes.map(({ path, Component }) => (
 | 
					        {routes.map(({ path, component }) => (
 | 
				
			||||||
            <Route
 | 
					          <Route key={path} path={path} component={component} exact />
 | 
				
			||||||
              key={path}
 | 
					 | 
				
			||||||
              path={path}
 | 
					 | 
				
			||||||
              render={() => (
 | 
					 | 
				
			||||||
                <React.Suspense fallback={<LoadingIndicatorPage />}>
 | 
					 | 
				
			||||||
                  <Component />
 | 
					 | 
				
			||||||
                </React.Suspense>
 | 
					 | 
				
			||||||
              )}
 | 
					 | 
				
			||||||
              exact
 | 
					 | 
				
			||||||
            />
 | 
					 | 
				
			||||||
        ))}
 | 
					        ))}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          {Object.values(settings).flatMap((section) =>
 | 
					        {pluginSettingsRoutes}
 | 
				
			||||||
            section.links.map(({ Component, to, exact }) => (
 | 
					 | 
				
			||||||
              <Route
 | 
					 | 
				
			||||||
                render={() => (
 | 
					 | 
				
			||||||
                  <React.Suspense fallback={<LoadingIndicatorPage />}>
 | 
					 | 
				
			||||||
                    <Component />
 | 
					 | 
				
			||||||
                  </React.Suspense>
 | 
					 | 
				
			||||||
                )}
 | 
					 | 
				
			||||||
                key={to}
 | 
					 | 
				
			||||||
                path={to}
 | 
					 | 
				
			||||||
                exact={exact || false}
 | 
					 | 
				
			||||||
              />
 | 
					 | 
				
			||||||
            ))
 | 
					 | 
				
			||||||
          )}
 | 
					 | 
				
			||||||
      </Switch>
 | 
					      </Switch>
 | 
				
			||||||
      )}
 | 
					 | 
				
			||||||
    </Layout>
 | 
					    </Layout>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -9,11 +9,11 @@ import {
 | 
				
			|||||||
  HeaderLayout,
 | 
					  HeaderLayout,
 | 
				
			||||||
  Layout,
 | 
					  Layout,
 | 
				
			||||||
  Link,
 | 
					  Link,
 | 
				
			||||||
 | 
					  Loader,
 | 
				
			||||||
  Main,
 | 
					  Main,
 | 
				
			||||||
  Typography,
 | 
					  Typography,
 | 
				
			||||||
} from '@strapi/design-system';
 | 
					} from '@strapi/design-system';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  LoadingIndicatorPage,
 | 
					 | 
				
			||||||
  prefixFileUrlWithBackendUrl,
 | 
					  prefixFileUrlWithBackendUrl,
 | 
				
			||||||
  SettingsPageTitle,
 | 
					  SettingsPageTitle,
 | 
				
			||||||
  useAPIErrorHandler,
 | 
					  useAPIErrorHandler,
 | 
				
			||||||
@ -161,7 +161,12 @@ const ApplicationInfosPage = () => {
 | 
				
			|||||||
      <SettingsPageTitle name="Application" />
 | 
					      <SettingsPageTitle name="Application" />
 | 
				
			||||||
      <Main>
 | 
					      <Main>
 | 
				
			||||||
        {isLoading ? (
 | 
					        {isLoading ? (
 | 
				
			||||||
          <LoadingIndicatorPage data-testid="loader" />
 | 
					          <Loader>
 | 
				
			||||||
 | 
					            {formatMessage({
 | 
				
			||||||
 | 
					              id: 'Settings.application.isLoading',
 | 
				
			||||||
 | 
					              defaultMessage: 'Loading',
 | 
				
			||||||
 | 
					            })}
 | 
				
			||||||
 | 
					          </Loader>
 | 
				
			||||||
        ) : (
 | 
					        ) : (
 | 
				
			||||||
          <form onSubmit={handleSubmit}>
 | 
					          <form onSubmit={handleSubmit}>
 | 
				
			||||||
            <HeaderLayout
 | 
					            <HeaderLayout
 | 
				
			||||||
 | 
				
			|||||||
@ -113,9 +113,9 @@ describe('Application page', () => {
 | 
				
			|||||||
  afterAll(() => server.close());
 | 
					  afterAll(() => server.close());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('should not display link upgrade version if not necessary', async () => {
 | 
					  it('should not display link upgrade version if not necessary', async () => {
 | 
				
			||||||
    const { queryByText, getByTestId } = setup();
 | 
					    const { queryByText } = setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await waitForElementToBeRemoved(() => getByTestId('loader'));
 | 
					    await waitForElementToBeRemoved(() => queryByText('Loading'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(queryByText('Upgrade your admin panel')).not.toBeInTheDocument();
 | 
					    expect(queryByText('Upgrade your admin panel')).not.toBeInTheDocument();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
@ -127,18 +127,18 @@ describe('Application page', () => {
 | 
				
			|||||||
      strapiVersion: '4.0.0',
 | 
					      strapiVersion: '4.0.0',
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const { getByText, getByTestId } = setup();
 | 
					    const { getByText, queryByText } = setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await waitForElementToBeRemoved(() => getByTestId('loader'));
 | 
					    await waitForElementToBeRemoved(() => queryByText('Loading'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(getByText('v4.0.0')).toBeInTheDocument();
 | 
					    expect(getByText('v4.0.0')).toBeInTheDocument();
 | 
				
			||||||
    expect(getByText('Upgrade your admin panel')).toBeInTheDocument();
 | 
					    expect(getByText('Upgrade your admin panel')).toBeInTheDocument();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('should render logo input if read permissions', async () => {
 | 
					  it('should render logo input if read permissions', async () => {
 | 
				
			||||||
    const { queryByText, getByTestId } = setup();
 | 
					    const { queryByText } = setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await waitForElementToBeRemoved(() => getByTestId('loader'));
 | 
					    await waitForElementToBeRemoved(() => queryByText('Loading'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(queryByText('Menu logo')).toBeInTheDocument();
 | 
					    expect(queryByText('Menu logo')).toBeInTheDocument();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
@ -153,9 +153,9 @@ describe('Application page', () => {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it('should render save button if update permissions', async () => {
 | 
					  it('should render save button if update permissions', async () => {
 | 
				
			||||||
    const { queryByText, getByTestId } = setup();
 | 
					    const { queryByText } = setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await waitForElementToBeRemoved(() => getByTestId('loader'));
 | 
					    await waitForElementToBeRemoved(() => queryByText('Loading'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(queryByText('Save')).toBeInTheDocument();
 | 
					    expect(queryByText('Save')).toBeInTheDocument();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
@ -163,9 +163,9 @@ describe('Application page', () => {
 | 
				
			|||||||
  it('should not render save button if no update permissions', async () => {
 | 
					  it('should not render save button if no update permissions', async () => {
 | 
				
			||||||
    useRBAC.mockReturnValue({ allowedActions: { canRead: true, canUpdate: false } });
 | 
					    useRBAC.mockReturnValue({ allowedActions: { canRead: true, canUpdate: false } });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const { queryByText, getByTestId } = setup();
 | 
					    const { queryByText } = setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await waitForElementToBeRemoved(() => getByTestId('loader'));
 | 
					    await waitForElementToBeRemoved(() => queryByText('Loading'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(queryByText('Save')).not.toBeInTheDocument();
 | 
					    expect(queryByText('Save')).not.toBeInTheDocument();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
@ -173,9 +173,9 @@ describe('Application page', () => {
 | 
				
			|||||||
  it('should update project settings on save', async () => {
 | 
					  it('should update project settings on save', async () => {
 | 
				
			||||||
    useRBAC.mockReturnValue({ allowedActions: { canRead: true, canUpdate: true } });
 | 
					    useRBAC.mockReturnValue({ allowedActions: { canRead: true, canUpdate: true } });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const { getByRole, getByTestId } = setup();
 | 
					    const { getByRole, queryByText } = setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await waitForElementToBeRemoved(() => getByTestId('loader'));
 | 
					    await waitForElementToBeRemoved(() => queryByText('Loading'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fireEvent.click(getByRole('button', { name: 'Save' }));
 | 
					    fireEvent.click(getByRole('button', { name: 'Save' }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -256,9 +256,7 @@ describe('ADMIN | pages | SettingsPage', () => {
 | 
				
			|||||||
              isDisplayed: true,
 | 
					              isDisplayed: true,
 | 
				
			||||||
              permissions: [],
 | 
					              permissions: [],
 | 
				
			||||||
              to: '/settings/internationalization',
 | 
					              to: '/settings/internationalization',
 | 
				
			||||||
              Component() {
 | 
					              Component: () => ({ default: () => <div>i18n settings</div> }),
 | 
				
			||||||
                return <div>i18n settings</div>;
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@ -272,9 +270,7 @@ describe('ADMIN | pages | SettingsPage', () => {
 | 
				
			|||||||
              isDisplayed: true,
 | 
					              isDisplayed: true,
 | 
				
			||||||
              permissions: [],
 | 
					              permissions: [],
 | 
				
			||||||
              to: '/settings/email-settings',
 | 
					              to: '/settings/email-settings',
 | 
				
			||||||
              Component() {
 | 
					              Component: () => ({ default: () => <div>email settings</div> }),
 | 
				
			||||||
                return <div>i18n settings</div>;
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@ -296,9 +292,7 @@ describe('ADMIN | pages | SettingsPage', () => {
 | 
				
			|||||||
            isDisplayed: true,
 | 
					            isDisplayed: true,
 | 
				
			||||||
            permissions: [],
 | 
					            permissions: [],
 | 
				
			||||||
            to: '/settings/internationalization',
 | 
					            to: '/settings/internationalization',
 | 
				
			||||||
            Component() {
 | 
					            Component: () => ({ default: () => <div>i18n settings</div> }),
 | 
				
			||||||
              return <div>i18n settings</div>;
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@ -312,9 +306,7 @@ describe('ADMIN | pages | SettingsPage', () => {
 | 
				
			|||||||
            isDisplayed: true,
 | 
					            isDisplayed: true,
 | 
				
			||||||
            permissions: [],
 | 
					            permissions: [],
 | 
				
			||||||
            to: '/settings/email-settings',
 | 
					            to: '/settings/email-settings',
 | 
				
			||||||
            Component() {
 | 
					            Component: () => ({ default: () => <div>email settings</div> }),
 | 
				
			||||||
              return <div>email settings</div>;
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
				
			|||||||
@ -135,7 +135,7 @@ describe('ADMIN | StrapiApp', () => {
 | 
				
			|||||||
      app.createSettingSection(section, links);
 | 
					      app.createSettingSection(section, links);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(app.settings.foo).toBeDefined();
 | 
					      expect(app.settings.foo).toBeDefined();
 | 
				
			||||||
      expect(app.settings.foo.links).toEqual(expect.any(Object));
 | 
					      expect(app.settings.foo.links).toEqual(links);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('should add a link correctly to the global section', () => {
 | 
					    it('should add a link correctly to the global section', () => {
 | 
				
			||||||
@ -150,7 +150,7 @@ describe('ADMIN | StrapiApp', () => {
 | 
				
			|||||||
      app.addSettingsLink('global', link);
 | 
					      app.addSettingsLink('global', link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(app.settings.global.links).toHaveLength(1);
 | 
					      expect(app.settings.global.links).toHaveLength(1);
 | 
				
			||||||
      expect(app.settings.global.links[0]).toEqual(expect.any(Object));
 | 
					      expect(app.settings.global.links[0]).toEqual(link);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('should add an array of links correctly to the global section', () => {
 | 
					    it('should add an array of links correctly to the global section', () => {
 | 
				
			||||||
@ -167,7 +167,7 @@ describe('ADMIN | StrapiApp', () => {
 | 
				
			|||||||
      app.addSettingsLinks('global', links);
 | 
					      app.addSettingsLinks('global', links);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(app.settings.global.links).toHaveLength(1);
 | 
					      expect(app.settings.global.links).toHaveLength(1);
 | 
				
			||||||
      expect(app.settings.global.links).toEqual(expect.any(Object));
 | 
					      expect(app.settings.global.links).toEqual(links);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -391,7 +391,7 @@ describe('ADMIN | StrapiApp', () => {
 | 
				
			|||||||
      app.addMenuLink(link);
 | 
					      app.addMenuLink(link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(app.menu[0]).toBeDefined();
 | 
					      expect(app.menu[0]).toBeDefined();
 | 
				
			||||||
      expect(app.menu[0]).toEqual(expect.any(Object));
 | 
					      expect(app.menu[0]).toEqual(link);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('addCorePluginMenuLink should add a link to the menu', () => {
 | 
					    it('addCorePluginMenuLink should add a link to the menu', () => {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										45
									
								
								packages/core/admin/admin/src/utils/createRoute.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								packages/core/admin/admin/src/utils/createRoute.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					import React, { useEffect, useState } from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { LoadingIndicatorPage } from '@strapi/helper-plugin';
 | 
				
			||||||
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
 | 
					import { Route } from 'react-router-dom';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const LazyCompo = ({ loadComponent }) => {
 | 
				
			||||||
 | 
					  const [Compo, setCompo] = useState(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    const loadCompo = async () => {
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        const loadedCompo = await loadComponent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        setCompo(() => loadedCompo.default);
 | 
				
			||||||
 | 
					      } catch (err) {
 | 
				
			||||||
 | 
					        // TODO return the error component
 | 
				
			||||||
 | 
					        console.log(err);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    loadCompo();
 | 
				
			||||||
 | 
					  }, [loadComponent]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (Compo) {
 | 
				
			||||||
 | 
					    return <Compo />;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return <LoadingIndicatorPage />;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LazyCompo.propTypes = {
 | 
				
			||||||
 | 
					  loadComponent: PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const createRoute = (Component, to, exact) => {
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <Route
 | 
				
			||||||
 | 
					      render={() => <LazyCompo loadComponent={Component} />}
 | 
				
			||||||
 | 
					      key={to}
 | 
				
			||||||
 | 
					      path={to}
 | 
				
			||||||
 | 
					      exact={exact || false}
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					import { createRoute } from '../createRoute';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('ADMIN | CONTAINER | SettingsPage | utils | createRoute', () => {
 | 
				
			||||||
 | 
					  it('should return a <Route /> with the correctProps', () => {
 | 
				
			||||||
 | 
					    const compo = () => 'test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const {
 | 
				
			||||||
 | 
					      props: { path, exact },
 | 
				
			||||||
 | 
					      key,
 | 
				
			||||||
 | 
					    } = createRoute(compo, '/test', true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(key).toEqual('/test');
 | 
				
			||||||
 | 
					    expect(exact).toBeTruthy();
 | 
				
			||||||
 | 
					    expect(path).toEqual('/test');
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@ -4,7 +4,7 @@ export const SETTINGS_ROUTES_EE = [
 | 
				
			|||||||
  ...(window.strapi.features.isEnabled(window.strapi.features.AUDIT_LOGS)
 | 
					  ...(window.strapi.features.isEnabled(window.strapi.features.AUDIT_LOGS)
 | 
				
			||||||
    ? [
 | 
					    ? [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          Component: React.lazy(() =>
 | 
					          component: React.lazy(() =>
 | 
				
			||||||
            import(
 | 
					            import(
 | 
				
			||||||
              /* webpackChunkName: "audit-logs-settings-page" */ './pages/AuditLogs/ProtectedListPage'
 | 
					              /* webpackChunkName: "audit-logs-settings-page" */ './pages/AuditLogs/ProtectedListPage'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@ -17,7 +17,7 @@ export const SETTINGS_ROUTES_EE = [
 | 
				
			|||||||
  ...(window.strapi.features.isEnabled(window.strapi.features.REVIEW_WORKFLOWS)
 | 
					  ...(window.strapi.features.isEnabled(window.strapi.features.REVIEW_WORKFLOWS)
 | 
				
			||||||
    ? [
 | 
					    ? [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          Component: React.lazy(() =>
 | 
					          component: React.lazy(() =>
 | 
				
			||||||
            import(
 | 
					            import(
 | 
				
			||||||
              /* webpackChunkName: "review-workflows-settings-list-view" */ './pages/ReviewWorkflows/pages/ListView'
 | 
					              /* webpackChunkName: "review-workflows-settings-list-view" */ './pages/ReviewWorkflows/pages/ListView'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@ -26,7 +26,7 @@ export const SETTINGS_ROUTES_EE = [
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          Component: React.lazy(() =>
 | 
					          component: React.lazy(() =>
 | 
				
			||||||
            import(
 | 
					            import(
 | 
				
			||||||
              /* webpackChunkName: "review-workflows-settings-create-view" */ './pages/ReviewWorkflows/pages/CreateView'
 | 
					              /* webpackChunkName: "review-workflows-settings-create-view" */ './pages/ReviewWorkflows/pages/CreateView'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@ -35,7 +35,7 @@ export const SETTINGS_ROUTES_EE = [
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          Component: React.lazy(() =>
 | 
					          component: React.lazy(() =>
 | 
				
			||||||
            import(
 | 
					            import(
 | 
				
			||||||
              /* webpackChunkName: "review-workflows-settings-edit-view" */ './pages/ReviewWorkflows/pages/EditView'
 | 
					              /* webpackChunkName: "review-workflows-settings-edit-view" */ './pages/ReviewWorkflows/pages/EditView'
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@ -48,7 +48,7 @@ export const SETTINGS_ROUTES_EE = [
 | 
				
			|||||||
  ...(window.strapi.features.isEnabled(window.strapi.features.SSO)
 | 
					  ...(window.strapi.features.isEnabled(window.strapi.features.SSO)
 | 
				
			||||||
    ? [
 | 
					    ? [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          Component: React.lazy(() =>
 | 
					          component: React.lazy(() =>
 | 
				
			||||||
            import(/* webpackChunkName: "sso-settings-page" */ './pages/SingleSignOn')
 | 
					            import(/* webpackChunkName: "sso-settings-page" */ './pages/SingleSignOn')
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
          path: '/settings/single-sign-on',
 | 
					          path: '/settings/single-sign-on',
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,13 @@ export default {
 | 
				
			|||||||
        defaultMessage: 'Content Types Builder',
 | 
					        defaultMessage: 'Content Types Builder',
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      permissions: PERMISSIONS.main,
 | 
					      permissions: PERMISSIONS.main,
 | 
				
			||||||
      Component: () => import(/* webpackChunkName: "content-type-builder" */ './pages/App'),
 | 
					      async Component() {
 | 
				
			||||||
 | 
					        const component = await import(
 | 
				
			||||||
 | 
					          /* webpackChunkName: "content-type-builder" */ './pages/App'
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return component;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    app.registerPlugin({
 | 
					    app.registerPlugin({
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,10 @@
 | 
				
			|||||||
 | 
					// NOTE TO PLUGINS DEVELOPERS:
 | 
				
			||||||
 | 
					// If you modify this file by adding new options to the plugin entry point
 | 
				
			||||||
 | 
					// Here's the file: strapi/docs/3.x/plugin-development/frontend-field-api.md
 | 
				
			||||||
 | 
					// Here's the file: strapi/docs/3.x/guides/registering-a-field-in-admin.md
 | 
				
			||||||
 | 
					// Also the strapi-generate-plugins/files/admin/src/index.js needs to be updated
 | 
				
			||||||
 | 
					// IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { prefixPluginTranslations } from '@strapi/helper-plugin';
 | 
					import { prefixPluginTranslations } from '@strapi/helper-plugin';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { PERMISSIONS } from './constants';
 | 
					import { PERMISSIONS } from './constants';
 | 
				
			||||||
@ -18,12 +25,17 @@ export default {
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          id: 'settings',
 | 
					          id: 'settings',
 | 
				
			||||||
          to: `/settings/email`,
 | 
					          to: `/settings/email`,
 | 
				
			||||||
          Component: () => import(/* webpackChunkName: "email-settings-page" */ './pages/Settings'),
 | 
					          async Component() {
 | 
				
			||||||
 | 
					            const component = await import(
 | 
				
			||||||
 | 
					              /* webpackChunkName: "email-settings-page" */ './pages/Settings'
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return component;
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          permissions: PERMISSIONS.settings,
 | 
					          permissions: PERMISSIONS.settings,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					 | 
				
			||||||
    app.registerPlugin({
 | 
					    app.registerPlugin({
 | 
				
			||||||
      id: 'email',
 | 
					      id: 'email',
 | 
				
			||||||
      name: 'email',
 | 
					      name: 'email',
 | 
				
			||||||
 | 
				
			|||||||
@ -83,8 +83,7 @@ StrapiAppProvider.propTypes = {
 | 
				
			|||||||
        defaultMessage: PropTypes.string.isRequired,
 | 
					        defaultMessage: PropTypes.string.isRequired,
 | 
				
			||||||
      }).isRequired,
 | 
					      }).isRequired,
 | 
				
			||||||
      permissions: PropTypes.array,
 | 
					      permissions: PropTypes.array,
 | 
				
			||||||
      // React.lazy loadable
 | 
					      Component: PropTypes.func,
 | 
				
			||||||
      Component: PropTypes.object,
 | 
					 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  ).isRequired,
 | 
					  ).isRequired,
 | 
				
			||||||
  plugins: PropTypes.object.isRequired,
 | 
					  plugins: PropTypes.object.isRequired,
 | 
				
			||||||
 | 
				
			|||||||
@ -108,4 +108,3 @@ export { setHexOpacity } from './utils/setHexOpacity';
 | 
				
			|||||||
export * from './utils/stopPropagation';
 | 
					export * from './utils/stopPropagation';
 | 
				
			||||||
export { translatedErrors } from './utils/translatedErrors';
 | 
					export { translatedErrors } from './utils/translatedErrors';
 | 
				
			||||||
export { wrapAxiosInstance } from './utils/wrapAxiosInstance';
 | 
					export { wrapAxiosInstance } from './utils/wrapAxiosInstance';
 | 
				
			||||||
export * from './utils/once';
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,9 @@
 | 
				
			|||||||
 | 
					// NOTE TO PLUGINS DEVELOPERS:
 | 
				
			||||||
 | 
					// If you modify this file by adding new options to the plugin entry point
 | 
				
			||||||
 | 
					// Here's the file: strapi/docs/3.0.0-beta.x/plugin-development/frontend-field-api.md
 | 
				
			||||||
 | 
					// Here's the file: strapi/docs/3.0.0-beta.x/guides/registering-a-field-in-admin.md
 | 
				
			||||||
 | 
					// Also the strapi-generate-plugins/files/admin/src/index.js needs to be updated
 | 
				
			||||||
 | 
					// IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
 | 
				
			||||||
import { prefixPluginTranslations } from '@strapi/helper-plugin';
 | 
					import { prefixPluginTranslations } from '@strapi/helper-plugin';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import pluginPkg from '../../package.json';
 | 
					import pluginPkg from '../../package.json';
 | 
				
			||||||
@ -21,7 +27,11 @@ export default {
 | 
				
			|||||||
        defaultMessage: 'Media Library',
 | 
					        defaultMessage: 'Media Library',
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      permissions: PERMISSIONS.main,
 | 
					      permissions: PERMISSIONS.main,
 | 
				
			||||||
      Component: () => import(/* webpackChunkName: "upload" */ './pages/App'),
 | 
					      async Component() {
 | 
				
			||||||
 | 
					        const component = await import(/* webpackChunkName: "upload" */ './pages/App');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return component;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    app.addFields({ type: 'media', Component: MediaLibraryInput });
 | 
					    app.addFields({ type: 'media', Component: MediaLibraryInput });
 | 
				
			||||||
@ -40,7 +50,13 @@ export default {
 | 
				
			|||||||
        defaultMessage: 'Media Library',
 | 
					        defaultMessage: 'Media Library',
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      to: '/settings/media-library',
 | 
					      to: '/settings/media-library',
 | 
				
			||||||
      Component: () => import(/* webpackChunkName: "upload-settings" */ './pages/SettingsPage'),
 | 
					      async Component() {
 | 
				
			||||||
 | 
					        const component = await import(
 | 
				
			||||||
 | 
					          /* webpackChunkName: "upload-settings" */ './pages/SettingsPage'
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return component;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      permissions: PERMISSIONS.settings,
 | 
					      permissions: PERMISSIONS.settings,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,13 @@ export default {
 | 
				
			|||||||
        defaultMessage: 'Documentation',
 | 
					        defaultMessage: 'Documentation',
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      permissions: PERMISSIONS.main,
 | 
					      permissions: PERMISSIONS.main,
 | 
				
			||||||
      Component: () => import(/* webpackChunkName: "documentation-page" */ './pages/PluginPage'),
 | 
					      async Component() {
 | 
				
			||||||
 | 
					        const component = await import(
 | 
				
			||||||
 | 
					          /* webpackChunkName: "documentation-page" */ './pages/PluginPage'
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return component;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    app.registerPlugin({
 | 
					    app.registerPlugin({
 | 
				
			||||||
@ -40,8 +46,13 @@ export default {
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
      id: 'documentation',
 | 
					      id: 'documentation',
 | 
				
			||||||
      to: `/settings/${pluginId}`,
 | 
					      to: `/settings/${pluginId}`,
 | 
				
			||||||
      Component: () =>
 | 
					      async Component() {
 | 
				
			||||||
        import(/* webpackChunkName: "documentation-settings" */ './pages/SettingsPage'),
 | 
					        const component = await import(
 | 
				
			||||||
 | 
					          /* webpackChunkName: "documentation-settings" */ './pages/SettingsPage'
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return component;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      permissions: PERMISSIONS.main,
 | 
					      permissions: PERMISSIONS.main,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
				
			|||||||
@ -61,7 +61,13 @@ export default {
 | 
				
			|||||||
      id: 'internationalization',
 | 
					      id: 'internationalization',
 | 
				
			||||||
      to: '/settings/internationalization',
 | 
					      to: '/settings/internationalization',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Component: () => import(/* webpackChunkName: "i18n-settings-page" */ './pages/SettingsPage'),
 | 
					      async Component() {
 | 
				
			||||||
 | 
					        const component = await import(
 | 
				
			||||||
 | 
					          /* webpackChunkName: "i18n-settings-page" */ './pages/SettingsPage'
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return component;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      permissions: PERMISSIONS.accessMain,
 | 
					      permissions: PERMISSIONS.accessMain,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -32,8 +32,13 @@ export default {
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          id: 'roles',
 | 
					          id: 'roles',
 | 
				
			||||||
          to: `/settings/users-permissions/roles`,
 | 
					          to: `/settings/users-permissions/roles`,
 | 
				
			||||||
          Component: () =>
 | 
					          async Component() {
 | 
				
			||||||
            import(/* webpackChunkName: "users-roles-settings-page" */ './pages/Roles'),
 | 
					            const component = await import(
 | 
				
			||||||
 | 
					              /* webpackChunkName: "users-roles-settings-page" */ './pages/Roles'
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return component;
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          permissions: PERMISSIONS.accessRoles,
 | 
					          permissions: PERMISSIONS.accessRoles,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@ -43,8 +48,13 @@ export default {
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          id: 'providers',
 | 
					          id: 'providers',
 | 
				
			||||||
          to: `/settings/users-permissions/providers`,
 | 
					          to: `/settings/users-permissions/providers`,
 | 
				
			||||||
          Component: () =>
 | 
					          async Component() {
 | 
				
			||||||
            import(/* webpackChunkName: "users-providers-settings-page" */ './pages/Providers'),
 | 
					            const component = await import(
 | 
				
			||||||
 | 
					              /* webpackChunkName: "users-providers-settings-page" */ './pages/Providers'
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return component;
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          permissions: PERMISSIONS.readProviders,
 | 
					          permissions: PERMISSIONS.readProviders,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@ -54,8 +64,13 @@ export default {
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          id: 'email-templates',
 | 
					          id: 'email-templates',
 | 
				
			||||||
          to: `/settings/users-permissions/email-templates`,
 | 
					          to: `/settings/users-permissions/email-templates`,
 | 
				
			||||||
          Component: () =>
 | 
					          async Component() {
 | 
				
			||||||
            import(/* webpackChunkName: "users-email-settings-page" */ './pages/EmailTemplates'),
 | 
					            const component = await import(
 | 
				
			||||||
 | 
					              /* webpackChunkName: "users-email-settings-page" */ './pages/EmailTemplates'
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return component;
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          permissions: PERMISSIONS.readEmailTemplates,
 | 
					          permissions: PERMISSIONS.readEmailTemplates,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@ -65,10 +80,13 @@ export default {
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          id: 'advanced-settings',
 | 
					          id: 'advanced-settings',
 | 
				
			||||||
          to: `/settings/users-permissions/advanced-settings`,
 | 
					          to: `/settings/users-permissions/advanced-settings`,
 | 
				
			||||||
          Component: () =>
 | 
					          async Component() {
 | 
				
			||||||
            import(
 | 
					            const component = await import(
 | 
				
			||||||
              /* webpackChunkName: "users-advanced-settings-page" */ './pages/AdvancedSettings'
 | 
					              /* webpackChunkName: "users-advanced-settings-page" */ './pages/AdvancedSettings'
 | 
				
			||||||
            ),
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return component;
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          permissions: PERMISSIONS.readAdvancedSettings,
 | 
					          permissions: PERMISSIONS.readAdvancedSettings,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user