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} -
    -

    - -

    -
      {pluginsLinks}
    -
    -
    -

    - -

    -
      - {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 ? ( + + <FormattedMessage id={id} defaultMessage={defaultMessage} /> + {searchable && ( + <SearchButton onClick={toggleSearch}> + <FontAwesomeIcon icon="search" /> + </SearchButton> + )} + + ) : ( + + <div> + <FontAwesomeIcon icon="search" /> + </div> + <Search + ref={ref} + onChange={handleChange} + value={search} + placeholder="search…" + /> + <SearchButton onClick={clearSearch}> + <FontAwesomeIcon icon="times" /> + </SearchButton> + + ); +}; + +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' + ), }, ];