Move configure button to the ctm

Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
soupette 2020-05-27 16:41:32 +02:00 committed by Alexandre Bodin
parent 79e347846a
commit 05f6fb7d40
7 changed files with 152 additions and 36 deletions

View File

@ -0,0 +1,40 @@
import React from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import { LayoutIcon } from 'strapi-helper-plugin';
import { Button as Base } from '@buffetjs/core';
import { useIntl } from 'react-intl';
const StyledButton = styled(Base)`
padding-left: 15px;
padding-right: 15px;
`;
const Button = ({ onClick, isTemporary }) => {
const { formatMessage } = useIntl();
const icon = <LayoutIcon className="colored" fill={isTemporary ? '#B4B6BA' : '#007eff'} />;
const label = formatMessage({ id: 'content-type-builder.form.button.configure-view' });
return (
<StyledButton
icon={icon}
label={label}
color="secondary"
onClick={onClick}
style={{ marginTop: '2px' }}
disabled={isTemporary}
/>
);
};
Button.defaultProps = {
isTemporary: false,
onClick: () => {},
};
Button.propTypes = {
isTemporary: PropTypes.bool,
onClick: PropTypes.func,
};
export default Button;

View File

@ -10,6 +10,7 @@ import pluginId from './pluginId';
import pluginLogo from './assets/images/logo.svg'; import pluginLogo from './assets/images/logo.svg';
import App from './containers/Main'; import App from './containers/Main';
import Initializer from './containers/Initializer'; import Initializer from './containers/Initializer';
import ConfigureViewButton from './InjectedComponents/ContentTypeBuilder/ConfigureViewButton';
import lifecycles from './lifecycles'; import lifecycles from './lifecycles';
import reducers from './reducers'; import reducers from './reducers';
import trads from './translations'; import trads from './translations';
@ -23,7 +24,14 @@ export default strapi => {
icon: pluginPkg.strapi.icon, icon: pluginPkg.strapi.icon,
id: pluginId, id: pluginId,
initializer: Initializer, initializer: Initializer,
injectedComponents: [], injectedComponents: [
{
plugin: 'content-type-builder.listView',
area: 'list.link',
component: ConfigureViewButton,
key: 'content-manager.link',
},
],
isReady: false, isReady: false,
isRequired: pluginPkg.strapi.required || false, isRequired: pluginPkg.strapi.required || false,
layout: null, layout: null,

View File

@ -1,10 +1,9 @@
import styled from 'styled-components'; import styled from 'styled-components';
import { Button } from '@buffetjs/core'; import { Button } from '@buffetjs/core';
/* eslint-disable */
const ListHeaderButton = styled(Button)` const ListHeaderButton = styled(Button)`
padding-left: 15px; padding-left: 15px;
padding-right: 15px; padding-right: 15px;
`; `;
export { ListHeaderButton }; export default ListHeaderButton;

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { ListHeaderButton } from '../ListButton';
import Title from './Title'; import Title from './Title';
import Wrapper from './Wrapper'; import Wrapper from './Wrapper';
@ -8,22 +8,7 @@ import Wrapper from './Wrapper';
function ListHeader({ actions, title }) { function ListHeader({ actions, title }) {
return ( return (
<Wrapper> <Wrapper>
<div className="list-header-actions"> <div className="list-header-actions">{actions}</div>
{actions.map(action => {
const { disabled, label, onClick } = action;
return (
<ListHeaderButton
key={label}
onClick={onClick}
disabled={disabled || false}
{...action}
>
{label}
</ListHeaderButton>
);
})}
</div>
<div className="list-header-title"> <div className="list-header-title">
{title.map(item => { {title.map(item => {
return <Title key={item}>{item}&nbsp;</Title>; return <Title key={item}>{item}&nbsp;</Title>;

View File

@ -1,20 +1,20 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import { Prompt, useHistory, useLocation } from 'react-router-dom'; import { Prompt, useHistory, useLocation } from 'react-router-dom';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { get, has, isEqual } from 'lodash'; import { get, has, isEqual } from 'lodash';
import { BackHeader, ListWrapper, useGlobalContext, LayoutIcon } from 'strapi-helper-plugin'; import { BackHeader, ListWrapper, useGlobalContext } from 'strapi-helper-plugin';
import { Header } from '@buffetjs/custom'; import { Header } from '@buffetjs/custom';
import ListViewContext from '../../contexts/ListViewContext'; import ListViewContext from '../../contexts/ListViewContext';
import convertAttrObjToArray from '../../utils/convertAttrObjToArray'; import convertAttrObjToArray from '../../utils/convertAttrObjToArray';
import getAttributeDisplayedType from '../../utils/getAttributeDisplayedType'; import getAttributeDisplayedType from '../../utils/getAttributeDisplayedType';
import pluginId from '../../pluginId';
import getComponents from '../../utils/getComponents';
import getTrad from '../../utils/getTrad'; import getTrad from '../../utils/getTrad';
import makeSearch from '../../utils/makeSearch'; import makeSearch from '../../utils/makeSearch';
import ListRow from '../../components/ListRow'; import ListRow from '../../components/ListRow';
import List from '../../components/List'; import List from '../../components/List';
import ListButton from '../../components/ListButton';
import useDataManager from '../../hooks/useDataManager'; import useDataManager from '../../hooks/useDataManager';
import pluginId from '../../pluginId';
import ListHeader from '../../components/ListHeader'; import ListHeader from '../../components/ListHeader';
import LeftMenu from '../LeftMenu'; import LeftMenu from '../LeftMenu';
import Wrapper from './Wrapper'; import Wrapper from './Wrapper';
@ -31,7 +31,7 @@ const ListView = () => {
toggleModalCancel, toggleModalCancel,
} = useDataManager(); } = useDataManager();
const { emitEvent, formatMessage } = useGlobalContext(); const { emitEvent, formatMessage, plugins } = useGlobalContext();
const { push, goBack } = useHistory(); const { push, goBack } = useHistory();
const { search } = useLocation(); const { search } = useLocation();
const [enablePrompt, togglePrompt] = useState(true); const [enablePrompt, togglePrompt] = useState(true);
@ -265,18 +265,17 @@ const ListView = () => {
} }
}; };
const configureButtonProps = { const listInjectedComponents = useMemo(() => {
icon: <LayoutIcon className="colored" fill={isTemporary ? '#B4B6BA' : '#007eff'} />, return getComponents('listView', 'list.link', plugins, {
color: 'secondary',
label: formatMessage({ id: `${pluginId}.form.button.configure-view` }),
onClick: goToCMSettingsPage, onClick: goToCMSettingsPage,
style: { marginTop: '2px' }, isTemporary,
disabled: isTemporary, });
}; // eslint-disable-next-line react-hooks/exhaustive-deps
}, [isTemporary]);
const listActions = isInDevelopmentMode const listActions = isInDevelopmentMode
? [{ ...configureButtonProps }, { ...addButtonProps }] ? [...listInjectedComponents, <ListButton {...addButtonProps} key="add-button" />]
: [configureButtonProps]; : listInjectedComponents;
const CustomRow = props => { const CustomRow = props => {
const { name } = props; const { name } = props;

View File

@ -0,0 +1,31 @@
import React from 'react';
import { get } from 'lodash';
import pluginId from '../pluginId';
/**
* Retrieve external links from injected components
* @type {Array} List of external links to display
*/
const getInjectedComponents = (container, area, plugins, rest) => {
const componentsToInject = Object.keys(plugins).reduce((acc, current) => {
// Retrieve injected compos from plugin
const currentPlugin = plugins[current];
const injectedComponents = get(currentPlugin, 'injectedComponents', []);
const compos = injectedComponents
.filter(compo => {
return compo.plugin === `${pluginId}.${container}` && compo.area === area;
})
.map(compo => {
const Component = compo.component;
return <Component {...compo} {...rest} key={compo.key} />;
});
return [...acc, ...compos];
}, []);
return componentsToInject;
};
export default getInjectedComponents;

View File

@ -0,0 +1,54 @@
import React from 'react';
import { shallow } from 'enzyme';
import getComponents from '../getComponents';
describe('Content Type Builder | utils | getComponents', () => {
it('should not crash', () => {
getComponents('', {}, '', '', '', jest.fn());
});
it('should return the correct components', () => {
const TestCompo1 = () => <div>TestCompo1</div>;
const TestCompo2 = () => <div>TestCompo2</div>;
const plugins = {
test: {
injectedComponents: [
{
plugin: 'content-type-builder.listView',
area: 'list.link',
component: TestCompo1,
key: 'test.TestCompo1',
props: {
someProps: { test: 'test' },
icon: 'fa-cog',
},
},
{
plugin: 'not.target.testContainer',
area: 'right.links',
component: TestCompo2,
key: 'test.TestCompo2',
props: {
someProps: { test: 'test' },
icon: 'fa-cog',
},
},
],
},
};
const container = shallow(
<div>
{getComponents('listView', 'list.link', plugins, 'test', 'test', 'test', jest.fn())}
</div>
);
expect(
getComponents('listView', 'list.link', plugins, 'test', 'test', 'test', jest.fn())
).toHaveLength(1);
expect(container.find(TestCompo1)).toHaveLength(1);
expect(container.find(TestCompo2)).toHaveLength(0);
});
});