mirror of
https://github.com/strapi/strapi.git
synced 2025-11-15 17:49:57 +00:00
Move configure button to the ctm
Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
parent
79e347846a
commit
05f6fb7d40
@ -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;
|
||||||
@ -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,
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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} </Title>;
|
return <Title key={item}>{item} </Title>;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user