diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/ComponentSelect/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/ComponentSelect/index.js
new file mode 100644
index 0000000000..966396e8af
--- /dev/null
+++ b/packages/strapi-plugin-content-type-builder/admin/src/components/ComponentSelect/index.js
@@ -0,0 +1,140 @@
+import React from 'react';
+import Select from 'react-select';
+import PropTypes from 'prop-types';
+import { SelectWrapper, SelectNav } from 'strapi-helper-plugin';
+import { ErrorMessage } from '@buffetjs/styles';
+import useDataManager from '../../hooks/useDataManager';
+
+const ComponentSelect = ({ error, label, onChange, name }) => {
+ const { componentsGroupedByCategory, components } = useDataManager();
+ console.log({ componentsGroupedByCategory });
+ const styles = {
+ container: base => ({
+ ...base,
+ 'z-index': 9999,
+ // padding: 0,
+ }),
+ control: (base, state) => ({
+ ...base,
+ 'z-index': 9999,
+ border: state.isFocused
+ ? '1px solid #78caff !important'
+ : error
+ ? '1px solid red !important'
+ : '1px solid #E3E9F3 !important',
+ }),
+ menu: base => {
+ return {
+ ...base,
+
+ border: '1px solid #78caff !important',
+ borderColor: '#78caff !important',
+ borderTopColor: '#E3E9F3 !important',
+ };
+ },
+ };
+ const Menu = props => {
+ console.log({ props });
+
+ return (
+
+
+ {Object.keys(componentsGroupedByCategory).map(categoryName => {
+ return (
+ -
+ {categoryName}
+
+ {componentsGroupedByCategory[categoryName].map(component => {
+ return - {component.schema.name}
;
+ })}
+
+
+ );
+ })}
+
+ {/*
*/}
+
+ );
+ };
+ const formattedOptions = Object.keys(componentsGroupedByCategory).reduce(
+ (acc, current) => {
+ const optionValueObject = componentsGroupedByCategory[current];
+ const option = {
+ label: current,
+ value: optionValueObject.map(val => val.uid),
+ // value:
+ options: optionValueObject.map(val => ({
+ label: val.schema.name,
+ value: val.uid,
+ })),
+ };
+
+ acc.push(option);
+ return acc;
+ },
+ []
+ );
+ const formattedOptions2 = Object.keys(components).reduce((acc, current) => {
+ const option = {
+ label: `${current} - ${components[current].schema.name}`,
+ value: current,
+ };
+
+ acc.push(option);
+
+ return acc;
+ }, []);
+
+ console.log(formattedOptions);
+ return (
+
+
+
+
+
+
+
+
+ {error && {error}}
+
+ );
+};
+
+ComponentSelect.defaultProps = {
+ error: null,
+};
+
+ComponentSelect.propTypes = {
+ error: PropTypes.string,
+ label: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ onChange: PropTypes.func.isRequired,
+};
+
+export default ComponentSelect;
diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js
index c8c347915b..73b3d3d631 100644
--- a/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js
+++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js
@@ -1,6 +1,6 @@
import React, { memo, useEffect, useReducer, useRef } from 'react';
import PropTypes from 'prop-types';
-import { get, sortBy } from 'lodash';
+import { get, groupBy, sortBy } from 'lodash';
import { request, LoadingIndicatorPage } from 'strapi-helper-plugin';
import { useLocation, useRouteMatch, Redirect } from 'react-router-dom';
import DataManagerContext from '../../contexts/DataManagerContext';
@@ -198,6 +198,7 @@ const DataManagerProvider = ({ allIcons, children }) => {
['schema', 'icon']
),
components,
+ componentsGroupedByCategory: groupBy(components, 'category'),
contentTypes,
createSchema,
allIcons,
diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js
index 2dfef8f8fe..c94d9e7070 100644
--- a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js
+++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js
@@ -21,6 +21,7 @@ import useDataManager from '../../hooks/useDataManager';
import AttributeOption from '../../components/AttributeOption';
import BooleanBox from '../../components/BooleanBox';
import ComponentIconPicker from '../../components/ComponentIconPicker';
+import ComponentSelect from '../../components/ComponentSelect';
import CustomCheckbox from '../../components/CustomCheckbox';
import CreatableSelect from '../../components/CreatableSelect';
import ModalHeader from '../../components/ModalHeader';
@@ -97,7 +98,6 @@ const FormModal = () => {
// This condition is added to prevent the reducer state to be cleared when navigating from the base tab to tha advanced one
state.modalType !== 'attribute'
) {
- console.log('ook');
const attributeToEditNotFormatted = get(
allDataSchema,
[...pathToSchema, 'schema', 'attributes', attributeName],
@@ -602,6 +602,7 @@ const FormModal = () => {
{
};
function LeftMenu() {
- const { components, contentTypes, sortedContentTypesList } = useDataManager();
+ const {
+ components,
+ componentsGroupedByCategory,
+ contentTypes,
+ sortedContentTypesList,
+ } = useDataManager();
const { currentEnvironment } = useGlobalContext();
const { push } = useHistory();
const isProduction = currentEnvironment === 'production';
- const grouped = groupBy(components, 'category');
const componentsData = sortBy(
- Object.keys(grouped).map(category => ({
+ Object.keys(componentsGroupedByCategory).map(category => ({
name: category,
title: category,
links: sortBy(
- grouped[category].map(compo => ({
+ componentsGroupedByCategory[category].map(compo => ({
name: compo.uid,
to: `/plugins/${pluginId}/component-categories/${category}/${compo.uid}`,
title: compo.schema.name,
diff --git a/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json b/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json
index de156a3756..16a4974017 100644
--- a/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json
+++ b/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json
@@ -211,6 +211,10 @@
"modalForm.attribute.text.type-selection": "Type",
"form.attribute.component.option.create": "Create a new component",
+ "form.attribute.component.option.repeatable": "Repeatable component",
+ "form.attribute.component.option.repeatable.description": "Best for multiple instances (array) of ingredients, meta tags, etc..",
+ "form.attribute.component.option.single": "Single component",
+ "form.attribute.component.option.single.description": "Best for grouping fields like full address, main information, etc...",
"form.attribute.component.option.create.description": "A component is shared across types, it will be available and accessible in your other components and content types as well.",
"form.attribute.component.option.reuse-existing": "Use an existing component",
"form.attribute.component.option.reuse-existing.description": "Reuse a component already created to keep your data consistent across content types.",
@@ -252,5 +256,6 @@
"modalForm.sub-header.attribute.create.step": "Add new component ({step})/2)",
"modalForm.sub-header.attribute.edit": "Edit {name}",
"modalForm.components.create-component.category.label": "Select a category or enter a name to create a new one",
+ "modalForm.attributes.select-component": "Select a component",
"modalForm.components.icon.label": "Icon"
}