diff --git a/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js b/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js
index 48d653fb98..a300d3e17d 100644
--- a/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js
+++ b/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js
@@ -6,6 +6,7 @@
import React from 'react';
import { defineMessages, FormattedMessage } from 'react-intl';
+import { useLocation } from 'react-router-dom';
import { PropTypes } from 'prop-types';
import LeftMenuLink from '../LeftMenuLink';
import Wrapper from './Wrapper';
@@ -13,7 +14,8 @@ import messages from './messages.json';
defineMessages(messages);
-function LeftMenuFooter({ version, ...rest }) {
+const LeftMenuFooter = ({ version }) => {
+ const location = useLocation();
const staticLinks = [
{
icon: 'book',
@@ -32,15 +34,20 @@ function LeftMenuFooter({ version, ...rest }) {
-
+
);
-}
+};
LeftMenuFooter.propTypes = {
version: PropTypes.string.isRequired,
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuHeader/index.js b/packages/strapi-admin/admin/src/components/LeftMenuHeader/index.js
index 2dec7a6c74..993583037b 100644
--- a/packages/strapi-admin/admin/src/components/LeftMenuHeader/index.js
+++ b/packages/strapi-admin/admin/src/components/LeftMenuHeader/index.js
@@ -1,22 +1,14 @@
-/**
- *
- * LeftMenuHeader
- *
- */
-
import React from 'react';
import { Link } from 'react-router-dom';
import Wrapper from './Wrapper';
-function LeftMenuHeader() {
- return (
-
-
-
-
-
- );
-}
+const LeftMenuHeader = () => (
+
+
+
+
+
+);
export default LeftMenuHeader;
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLink/A.js b/packages/strapi-admin/admin/src/components/LeftMenuLink/A.js
new file mode 100644
index 0000000000..c7a6ba2208
--- /dev/null
+++ b/packages/strapi-admin/admin/src/components/LeftMenuLink/A.js
@@ -0,0 +1,39 @@
+import styled from 'styled-components';
+
+const A = styled.a`
+ position: relative;
+ padding-top: 0.8rem;
+ padding-bottom: 0.2rem;
+ padding-left: 1.6rem;
+ min-height: 3.6rem;
+ border-left: 0.3rem solid transparent;
+ cursor: pointer;
+ color: ${props => props.theme.main.colors.leftMenu['link-color']};
+ text-decoration: none;
+ display: block;
+ -webkit-font-smoothing: antialiased;
+
+ &:hover {
+ color: ${props => props.theme.main.colors.white};
+ background: ${props => props.theme.main.colors.leftMenu['link-hover']};
+
+ border-left: 0.3rem solid ${props => props.theme.main.colors.strapi.blue};
+ text-decoration: none;
+ }
+
+ &:focus {
+ color: ${props => props.theme.main.colors.white};
+ text-decoration: none;
+ }
+
+ &:visited {
+ color: ${props => props.theme.main.colors.leftMenu['link-color']};
+ }
+
+ &.linkActive {
+ color: white !important;
+ border-left: 0.3rem solid ${props => props.theme.main.colors.strapi.blue};
+ }
+`;
+
+export default A;
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLink/LeftMenuIcon.js b/packages/strapi-admin/admin/src/components/LeftMenuLink/LeftMenuIcon.js
new file mode 100644
index 0000000000..35c3e83c67
--- /dev/null
+++ b/packages/strapi-admin/admin/src/components/LeftMenuLink/LeftMenuIcon.js
@@ -0,0 +1,28 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import styled from 'styled-components';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+
+const FaIcon = styled(({ small, ...props }) => )`
+ position: absolute;
+ top: calc(50% - 0.9rem + 0.5rem);
+ left: 1.6rem;
+ margin-right: 1.2rem;
+ font-size: ${props => (props.small ? '1rem' : '1.4rem')};
+ width: 1.4rem;
+ padding-bottom: 0.2rem;
+ text-align: center;
+`;
+
+const LeftMenuIcon = ({ icon }) => (
+
+);
+
+LeftMenuIcon.propTypes = {
+ icon: PropTypes.string,
+};
+LeftMenuIcon.defaultProps = {
+ icon: 'circle',
+};
+
+export default LeftMenuIcon;
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLink/LeftMenuLinkContent.js b/packages/strapi-admin/admin/src/components/LeftMenuLink/LeftMenuLinkContent.js
new file mode 100644
index 0000000000..2d90cde812
--- /dev/null
+++ b/packages/strapi-admin/admin/src/components/LeftMenuLink/LeftMenuLinkContent.js
@@ -0,0 +1,96 @@
+/**
+ *
+ * LeftMenuLink
+ *
+ */
+
+import React from 'react';
+import { startsWith } from 'lodash';
+import PropTypes from 'prop-types';
+import { FormattedMessage } from 'react-intl';
+import styled from 'styled-components';
+import { Link, withRouter } from 'react-router-dom';
+
+import en from '../../translations/en.json';
+import LeftMenuIcon from './LeftMenuIcon';
+import A from './A';
+
+const LinkLabel = styled.span`
+ display: inline-block;
+ width: 100%;
+ padding-right: 1rem;
+ padding-left: 2.6rem;
+`;
+
+const LeftMenuLinkContent = ({
+ destination,
+ iconName,
+ label,
+ location,
+ source,
+ suffixUrlToReplaceForLeftMenuHighlight,
+}) => {
+ const isLinkActive = startsWith(
+ location.pathname.replace('/admin', '').concat('/'),
+
+ destination.replace(suffixUrlToReplaceForLeftMenuHighlight, '').concat('/')
+ );
+
+ // Check if messageId exists in en locale to prevent warning messages
+ const content = en[label] ? (
+
+ {message => {message}}
+
+ ) : (
+ {label}
+ );
+
+ // Create external or internal link.
+ return destination.includes('http') ? (
+
+
+ {content}
+
+ ) : (
+
+
+ {content}
+
+ );
+};
+
+LeftMenuLinkContent.propTypes = {
+ destination: PropTypes.string.isRequired,
+ iconName: PropTypes.string.isRequired,
+ label: PropTypes.string.isRequired,
+ location: PropTypes.shape({
+ pathname: PropTypes.string,
+ }).isRequired,
+ source: PropTypes.string,
+ suffixUrlToReplaceForLeftMenuHighlight: PropTypes.string,
+};
+
+LeftMenuLinkContent.defaultProps = {
+ source: '',
+ suffixUrlToReplaceForLeftMenuHighlight: '',
+};
+
+export default withRouter(LeftMenuLinkContent);
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLink/Li.js b/packages/strapi-admin/admin/src/components/LeftMenuLink/Li.js
deleted file mode 100644
index bc040007cf..0000000000
--- a/packages/strapi-admin/admin/src/components/LeftMenuLink/Li.js
+++ /dev/null
@@ -1,129 +0,0 @@
-import styled from 'styled-components';
-import PropTypes from 'prop-types';
-
-const Li = styled.li`
- position: relative;
- overflow: hidden;
-
- &.dotted-link {
- background: red;
- }
-
- &:not(:first-child) {
- margin-top: 0;
- }
-
- .plugin {
- cursor: pointer;
- position: absolute;
- top: 10px;
- left: calc(100% - 4px);
- display: inline-block;
- width: auto;
- height: 20px;
- transition: right 1s ease-in-out;
-
- span {
- display: inline-block;
- overflow: hidden;
- width: auto;
- height: 20px;
- padding: 0 14px 0 10px;
- color: #ffffff;
- font-size: 12px;
- line-height: 20px;
- background: #0097f7;
- border-radius: 3px;
- transition: transform 0.3s ease-in-out;
- white-space: pre;
-
- &:hover {
- transform: translateX(calc(-100% + 9px));
- }
- }
- }
-
- .link {
- position: relative;
- padding-top: 0.8rem;
- padding-bottom: 0.2rem;
- padding-left: 1.6rem;
- min-height: 3.6rem;
- border-left: 0.3rem solid transparent;
- cursor: pointer;
- color: ${props => props.theme.main.colors.leftMenu['link-color']};
- text-decoration: none;
- display: block;
- -webkit-font-smoothing: antialiased;
-
- &:hover {
- color: ${props => props.theme.main.colors.white};
- background: ${props => props.theme.main.colors.leftMenu['link-hover']};
-
- border-left: 0.3rem solid ${props => props.theme.main.colors.strapi.blue};
- text-decoration: none;
- }
-
- &:focus {
- color: ${props => props.theme.main.colors.white};
- text-decoration: none;
- }
-
- &:visited {
- color: ${props => props.theme.main.colors.leftMenu['link-color']};
- }
- span {
- display: inline-block;
- width: 100%;
- padding-right: 1rem;
- padding-left: 2.6rem;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- }
-
- .linkActive {
- color: white !important;
- border-left: 0.3rem solid ${props => props.theme.main.colors.strapi.blue};
- }
-
- .linkIcon {
- position: absolute;
- top: calc(50% - 0.9rem + 0.5rem);
- left: 1.6rem;
- margin-right: 1.2rem;
- font-size: 1.4rem;
- width: 1.4rem;
- padding-bottom: 0.2rem;
- text-align: center;
- }
-
- .linkLabel {
- display: inline-block;
- width: 100%;
- padding-right: 1rem;
- padding-left: 2.6rem;
- }
-`;
-
-Li.defaultProps = {
- theme: {
- main: {
- colors: {
- leftMenu: {},
- strapi: {},
- },
- sizes: {
- header: {},
- leftMenu: {},
- },
- },
- },
-};
-
-Li.propTypes = {
- theme: PropTypes.object,
-};
-
-export default Li;
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLink/Plugin.js b/packages/strapi-admin/admin/src/components/LeftMenuLink/Plugin.js
new file mode 100644
index 0000000000..bad4677129
--- /dev/null
+++ b/packages/strapi-admin/admin/src/components/LeftMenuLink/Plugin.js
@@ -0,0 +1,33 @@
+import styled from 'styled-components';
+
+const Plugin = styled.div`
+ cursor: pointer;
+ position: absolute;
+ top: 10px;
+ left: calc(100% - 4px);
+ display: inline-block;
+ width: auto;
+ height: 20px;
+ transition: right 1s ease-in-out;
+
+ span {
+ display: inline-block;
+ overflow: hidden;
+ width: auto;
+ height: 20px;
+ padding: 0 14px 0 10px;
+ color: #ffffff;
+ font-size: 12px;
+ line-height: 20px;
+ background: #0097f7;
+ border-radius: 3px;
+ transition: transform 0.3s ease-in-out;
+ white-space: pre;
+
+ &:hover {
+ transform: translateX(calc(-100% + 9px));
+ }
+ }
+`;
+
+export default Plugin;
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js b/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js
index 93e2c086d0..a39704a7af 100644
--- a/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js
+++ b/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js
@@ -5,98 +5,59 @@
*/
import React from 'react';
-import { startsWith, upperFirst } from 'lodash';
+import { upperFirst } from 'lodash';
import PropTypes from 'prop-types';
-import { FormattedMessage } from 'react-intl';
-import { Link } from 'react-router-dom';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import en from '../../translations/en.json';
-import Li from './Li';
-/* eslint-disable */
-
-function LeftMenuLink(props) {
- const isLinkActive = startsWith(
- props.location.pathname.replace('/admin', '').concat('/'),
-
- props.destination
- .replace(props.suffixUrlToReplaceForLeftMenuHighlight, '')
- .concat('/')
- );
+import LeftMenuLinkContent from './LeftMenuLinkContent';
+import Plugin from './Plugin';
+const LeftMenuLink = ({
+ destination,
+ iconName,
+ label,
+ location,
+ source,
+ suffixUrlToReplaceForLeftMenuHighlight,
+}) => {
const plugin =
- props.source !== 'content-manager' && props.source !== '' ? (
-
- {upperFirst(props.source.split('-').join(' '))}
-
+ source !== 'content-manager' && source !== '' ? (
+
+ {upperFirst(source.split('-').join(' '))}
+
) : (
''
);
- // Check if messageId exists in en locale to prevent warning messages
- const content = en[props.label] ? (
-
- ) : (
-
{props.label}
- );
-
- // Icon.
-
- const icon =
;
-
- // Create external or internal link.
- const link = props.destination.includes('http') ? (
-
- {icon}
- {content}
-
- ) : (
-
- {icon}
- {content}
-
- );
-
return (
-
- {link}
+ <>
+
{plugin}
-
+ >
);
-}
+};
LeftMenuLink.propTypes = {
destination: PropTypes.string.isRequired,
- icon: PropTypes.string.isRequired,
+ iconName: PropTypes.string,
label: PropTypes.string.isRequired,
location: PropTypes.shape({
pathname: PropTypes.string,
}).isRequired,
- pluginSuffixUrl: PropTypes.string,
source: PropTypes.string,
suffixUrlToReplaceForLeftMenuHighlight: PropTypes.string,
};
LeftMenuLink.defaultProps = {
- pluginSuffixUrl: '',
+ iconName: 'circle',
source: '',
suffixUrlToReplaceForLeftMenuHighlight: '',
};
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/index.js b/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/index.js
index cbe8f3136f..80d5fd4f79 100644
--- a/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/index.js
+++ b/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/index.js
@@ -1,27 +1,24 @@
-/**
- *
- * LeftMenuLinkContainer
- *
- */
-
import React from 'react';
+import { useLocation } from 'react-router-dom';
import PropTypes from 'prop-types';
-import { FormattedMessage } from 'react-intl';
-import { get, snakeCase, isEmpty, map, sortBy } from 'lodash';
+import { get, snakeCase, isEmpty } from 'lodash';
+
import { SETTINGS_BASE_URL } from '../../config';
-import LeftMenuLink from '../LeftMenuLink';
import Wrapper from './Wrapper';
import messages from './messages.json';
-/* eslint-disable */
+import LeftMenuLinkSection from '../LeftMenuLinkSection';
-function LeftMenuLinkContainer({ plugins, ...rest }) {
- // Generate the list of sections
- const pluginsSections = Object.keys(plugins).reduce((acc, current) => {
+const LeftMenuLinkContainer = ({ plugins }) => {
+ const location = useLocation();
+
+ // Generate the list of content types sections
+ const contentTypesSections = Object.keys(plugins).reduce((acc, current) => {
plugins[current].leftMenuSections.forEach((section = {}) => {
if (!isEmpty(section.links)) {
acc[snakeCase(section.name)] = {
name: section.name,
+ searchable: true,
links: get(acc[snakeCase(section.name)], 'links', []).concat(
section.links
.filter(link => link.isDisplayed !== false)
@@ -40,109 +37,70 @@ function LeftMenuLinkContainer({ plugins, ...rest }) {
return acc;
}, {});
- const linkSections = Object.keys(pluginsSections).map((current, j) => {
- const contentTypes = pluginsSections[current].links;
-
- return (
-
-
-
- {title => title}
-
-
-
- {sortBy(contentTypes, 'label').map((link, i) => (
-
- ))}
-
-
- );
- });
-
- // Check if the plugins list is empty or not and display plugins by name
- const pluginsLinks = !isEmpty(plugins) ? (
- map(sortBy(plugins, 'name'), plugin => {
- const shouldInjectPlugin = !!plugin.mainComponent;
-
- if (
+ // Generate the list of plugin links
+ const pluginsLinks = Object.values(plugins)
+ .filter(
+ plugin =>
plugin.id !== 'email' &&
plugin.id !== 'content-manager' &&
- shouldInjectPlugin
- ) {
- const pluginSuffixUrl = plugin.suffixUrl
- ? plugin.suffixUrl(plugins)
- : '';
+ !!plugin.mainComponent
+ )
+ .map(plugin => {
+ const pluginSuffixUrl = plugin.suffixUrl ? plugin.suffixUrl(plugins) : '';
- const destination = `/plugins/${get(plugin, 'id')}${pluginSuffixUrl}`;
+ return {
+ icon: get(plugin, 'icon') || 'plug',
+ label: get(plugin, 'name'),
+ destination: `/plugins/${get(plugin, 'id')}${pluginSuffixUrl}`,
+ };
+ });
- return (
-
- );
- }
- })
- ) : (
-
- .
-
- );
-
- const staticLinks = [
- {
- icon: 'list',
- label: messages.listPlugins.id,
- destination: '/list-plugins',
+ const menu = {
+ ...contentTypesSections,
+ plugins: {
+ searchable: false,
+ name: 'plugins',
+ emptyLinksListMessage: messages.noPluginsInstalled.id,
+ links: pluginsLinks,
},
- {
- icon: 'shopping-basket',
- label: messages.installNewPlugin.id,
- destination: '/marketplace',
+ general: {
+ searchable: false,
+ name: 'general',
+ links: [
+ {
+ icon: 'list',
+ label: messages.listPlugins.id,
+ destination: '/list-plugins',
+ },
+ {
+ icon: 'shopping-basket',
+ label: messages.installNewPlugin.id,
+ destination: '/marketplace',
+ },
+ {
+ icon: 'cog',
+ label: messages.settings.id,
+ destination: SETTINGS_BASE_URL,
+ },
+ ],
},
- {
- icon: 'cog',
- label: messages.settings.id,
- destination: SETTINGS_BASE_URL,
- },
- ];
+ };
return (
- {linkSections}
-
-
-
-
-
-
- {staticLinks.map(link => (
-
- ))}
-
-
+ {Object.keys(menu).map(current => (
+
+ ))}
);
-}
+};
LeftMenuLinkContainer.propTypes = {
plugins: PropTypes.object.isRequired,
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/messages.json b/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/messages.json
index 9bf65bf719..ff97b58916 100644
--- a/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/messages.json
+++ b/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/messages.json
@@ -3,6 +3,10 @@
"id": "app.components.LeftMenuLinkContainer.contentTypes",
"defaultMessage": "Collection Types"
},
+ "singleTypes": {
+ "id": "app.components.LeftMenuLinkContainer.singleTypes",
+ "defaultMessage": "Single Types"
+ },
"listPlugins": {
"id": "app.components.LeftMenuLinkContainer.listPlugins",
"defaultMessage": "Plugins"
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLinkHeader/Search.js b/packages/strapi-admin/admin/src/components/LeftMenuLinkHeader/Search.js
new file mode 100644
index 0000000000..887e7efebd
--- /dev/null
+++ b/packages/strapi-admin/admin/src/components/LeftMenuLinkHeader/Search.js
@@ -0,0 +1,11 @@
+import styled from 'styled-components';
+
+const Search = styled.input`
+ width: 100%;
+ padding: 0 21px;
+ outline: 0;
+ font-size: 1.3rem;
+ color: ${props => props.theme.main.colors.white};
+`;
+
+export default Search;
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLinkHeader/index.js b/packages/strapi-admin/admin/src/components/LeftMenuLinkHeader/index.js
new file mode 100644
index 0000000000..bc4ca1c46f
--- /dev/null
+++ b/packages/strapi-admin/admin/src/components/LeftMenuLinkHeader/index.js
@@ -0,0 +1,92 @@
+import React, { useState, createRef, useEffect } from 'react';
+import { camelCase } from 'lodash';
+import PropTypes from 'prop-types';
+import { FormattedMessage } from 'react-intl';
+import styled from 'styled-components';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+
+import messages from '../LeftMenuLinkContainer/messages.json';
+import Search from './Search';
+
+const Title = styled.div`
+ display: flex;
+ justify-content: space-between;
+ padding-left: 2rem;
+ padding-right: 1.6rem;
+ padding-top: 0.7rem;
+ margin-bottom: 0.8rem;
+ color: ${props => props.theme.main.colors.leftMenu['title-color']};
+ text-transform: uppercase;
+ font-size: 1.1rem;
+ letter-spacing: 0.1rem;
+ font-weight: 800;
+`;
+const SearchButton = styled.button`
+ padding: 0 10px;
+`;
+
+const LeftMenuLinkHeader = ({ section, searchable, setSearch, search }) => {
+ const [showSearch, setShowSearch] = useState(false);
+ const ref = createRef();
+ const { id, defaultMessage } = messages[camelCase(section)];
+
+ useEffect(() => {
+ if (showSearch && ref.current) {
+ ref.current.focus();
+ }
+ }, [ref, showSearch]);
+
+ const toggleSearch = () => {
+ setShowSearch(prev => !prev);
+ };
+
+ const handleChange = ({ target: { value } }) => {
+ setSearch(value);
+ };
+
+ const clearSearch = () => {
+ setSearch('');
+ setShowSearch(false);
+ };
+
+ return !showSearch ? (
+
+
+ {searchable && (
+
+
+
+ )}
+
+ ) : (
+
+
+
+
+
+
+
+
+
+ );
+};
+
+LeftMenuLinkHeader.propTypes = {
+ section: PropTypes.string.isRequired,
+ searchable: PropTypes.bool,
+ setSearch: PropTypes.func,
+ search: PropTypes.string,
+};
+
+LeftMenuLinkHeader.defaultProps = {
+ search: null,
+ searchable: false,
+ setSearch: () => {},
+};
+
+export default LeftMenuLinkHeader;
diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLinkSection/index.js b/packages/strapi-admin/admin/src/components/LeftMenuLinkSection/index.js
new file mode 100644
index 0000000000..fc5bda113d
--- /dev/null
+++ b/packages/strapi-admin/admin/src/components/LeftMenuLinkSection/index.js
@@ -0,0 +1,94 @@
+import React, { useState } from 'react';
+import PropTypes from 'prop-types';
+import matchSorter from 'match-sorter';
+import styled from 'styled-components';
+import { sortBy } from 'lodash';
+import { FormattedMessage } from 'react-intl';
+
+import LeftMenuLink from '../LeftMenuLink';
+import LeftMenuLinkHeader from '../LeftMenuLinkHeader';
+
+const LeftMenuListLink = styled.div`
+ max-height: 180px;
+ overflow: auto;
+`;
+const EmptyLinksList = styled.div`
+ color: ${props => props.theme.main.colors.white};
+ padding-left: 1.6rem;
+ padding-right: 1.6rem;
+ font-weight: 300;
+ min-height: 3.6rem;
+ padding-top: 0.2rem;
+`;
+
+const LeftMenuLinksSection = ({
+ section,
+ searchable,
+ location,
+ links,
+ emptyLinksListMessage,
+}) => {
+ const [search, setSearch] = useState('');
+
+ const filteredList = sortBy(
+ matchSorter(links, search, {
+ keys: ['label'],
+ }),
+ 'label'
+ );
+
+ const getLinkDestination = link => {
+ return ['plugins', 'general'].includes(section)
+ ? link.destination
+ : `/plugins/${link.plugin}/${link.destination || link.uid}`;
+ };
+
+ return (
+ <>
+
+
+ {filteredList.length > 0 ? (
+ filteredList.map((link, index) => (
+
+ ))
+ ) : (
+
+
+
+ )}
+
+ >
+ );
+};
+
+LeftMenuLinksSection.propTypes = {
+ section: PropTypes.string.isRequired,
+ searchable: PropTypes.bool.isRequired,
+ location: PropTypes.shape({
+ pathname: PropTypes.string,
+ }).isRequired,
+ links: PropTypes.arrayOf(PropTypes.object).isRequired,
+ emptyLinksListMessage: PropTypes.string,
+};
+
+LeftMenuLinksSection.defaultProps = {
+ emptyLinksListMessage: 'components.ListRow.empty',
+};
+
+export default LeftMenuLinksSection;
diff --git a/packages/strapi-admin/admin/src/containers/LeftMenu/index.js b/packages/strapi-admin/admin/src/containers/LeftMenu/index.js
index 7268e9f334..8969da6e86 100644
--- a/packages/strapi-admin/admin/src/containers/LeftMenu/index.js
+++ b/packages/strapi-admin/admin/src/containers/LeftMenu/index.js
@@ -5,20 +5,23 @@
*/
import React from 'react';
-import { withRouter } from 'react-router-dom';
+import PropTypes from 'prop-types';
import LeftMenuHeader from '../../components/LeftMenuHeader';
import LeftMenuLinkContainer from '../../components/LeftMenuLinkContainer';
import LeftMenuFooter from '../../components/LeftMenuFooter';
import Wrapper from './Wrapper';
-function LeftMenu(props) {
- return (
-
-
-
-
-
- );
-}
+const LeftMenu = ({ version, plugins }) => (
+
+
+
+
+
+);
-export default withRouter(LeftMenu);
+LeftMenu.propTypes = {
+ version: PropTypes.string.isRequired,
+ plugins: PropTypes.object.isRequired,
+};
+
+export default LeftMenu;
diff --git a/packages/strapi-admin/admin/src/translations/en.json b/packages/strapi-admin/admin/src/translations/en.json
index 591000cb9f..3ce50c4e62 100644
--- a/packages/strapi-admin/admin/src/translations/en.json
+++ b/packages/strapi-admin/admin/src/translations/en.json
@@ -77,6 +77,7 @@
"app.components.LeftMenuLinkContainer.installNewPlugin": "Marketplace",
"app.components.LeftMenuLinkContainer.listPlugins": "Plugins",
"app.components.LeftMenuLinkContainer.contentTypes": "Collection Types",
+ "app.components.LeftMenuLinkContainer.singleTypes": "Single Types",
"app.components.LeftMenuLinkContainer.noPluginsInstalled": "No plugins installed yet",
"app.components.LeftMenuLinkContainer.plugins": "Plugins",
"app.components.LeftMenuLinkContainer.settings": "Settings",
diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Initializer/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/Initializer/index.js
index 6caefa0e43..bae10b3ec9 100644
--- a/packages/strapi-plugin-content-manager/admin/src/containers/Initializer/index.js
+++ b/packages/strapi-plugin-content-manager/admin/src/containers/Initializer/index.js
@@ -21,11 +21,18 @@ const Initializer = ({ updatePlugin }) => {
try {
const { data } = await request(requestURL, { method: 'GET' });
-
const menu = [
{
name: 'Content Types',
- links: data,
+ links: data.filter(
+ contentType => contentType.schema.kind === 'collectionType'
+ ),
+ },
+ {
+ name: 'Single Types',
+ links: data.filter(
+ contentType => contentType.schema.kind === 'singleType'
+ ),
},
];