252 lines
8.5 KiB
JavaScript
Raw Normal View History

import React, {
memo,
useCallback,
useMemo,
useEffect,
useReducer,
useRef,
} from 'react';
2019-07-11 11:35:18 +02:00
import PropTypes from 'prop-types';
2019-10-30 14:47:12 +01:00
import { get } from 'lodash';
import { useHistory, useLocation } from 'react-router-dom';
import { BackHeader, getQueryParameters, LiLink } from 'strapi-helper-plugin';
2019-07-11 11:35:18 +02:00
import pluginId from '../../pluginId';
import Container from '../../components/Container';
import DynamicZone from '../../components/DynamicZone';
import FormWrapper from '../../components/FormWrapper';
// import ComponentField from '../../components/ComponentField';
2019-10-30 15:32:29 +01:00
import Inputs from '../../components/Inputs';
2019-10-30 14:47:12 +01:00
import SelectWrapper from '../../components/SelectWrapper';
import EditViewDataManagerProvider from '../EditViewDataManagerProvider';
2019-10-31 11:57:40 +01:00
import EditViewProvider from '../EditViewProvider';
2019-10-30 14:47:12 +01:00
import Header from './Header';
2019-08-22 17:15:15 +02:00
import getInjectedComponents from './utils/getComponents';
import init from './init';
2019-07-11 11:35:18 +02:00
import reducer, { initialState } from './reducer';
2019-10-30 19:06:40 +01:00
import { LinkWrapper, SubWrapper } from './components';
import createAttributesLayout from './utils/createAttributesLayout';
const EditView = ({
2019-07-11 16:53:00 +02:00
currentEnvironment,
emitEvent,
2019-07-11 11:35:18 +02:00
layouts,
2019-07-11 16:53:00 +02:00
plugins,
slug,
}) => {
const formatLayoutRef = useRef();
formatLayoutRef.current = createAttributesLayout;
// Retrieve push to programmatically navigate between views
const { push } = useHistory();
// Retrieve the search
const { search } = useLocation();
// eslint-disable-next-line react-hooks/exhaustive-deps
2019-07-11 11:35:18 +02:00
const [reducerState, dispatch] = useReducer(reducer, initialState, () =>
init(initialState)
);
2019-10-30 18:46:19 +01:00
const allLayoutData = useMemo(() => get(layouts, [slug], {}), [
layouts,
slug,
]);
const currentContentTypeLayoutData = useMemo(
2019-10-30 18:46:19 +01:00
() => get(allLayoutData, ['contentType'], {}),
[allLayoutData]
);
const currentContentTypeLayout = useMemo(
() => get(currentContentTypeLayoutData, ['layouts', 'edit'], []),
[currentContentTypeLayoutData]
);
const currentContentTypeLayoutRelations = useMemo(
() => get(currentContentTypeLayoutData, ['layouts', 'editRelations'], []),
[currentContentTypeLayoutData]
);
const currentContentTypeSchema = useMemo(
() => get(currentContentTypeLayoutData, ['schema'], {}),
[currentContentTypeLayoutData]
2019-07-11 11:35:18 +02:00
);
const source = getQueryParameters(search, 'source');
const getFieldType = useCallback(
fieldName => {
return get(
currentContentTypeSchema,
['attributes', fieldName, 'type'],
''
);
},
[currentContentTypeSchema]
);
// Check if a block is a dynamic zone
const isDynamicZone = useCallback(
block => {
return block.every(subBlock => {
return subBlock.every(obj => getFieldType(obj.name) === 'dynamiczone');
});
},
[getFieldType]
);
2019-07-11 11:35:18 +02:00
useEffect(() => {
2019-09-16 17:47:43 +02:00
// Force state to be cleared when navigation from one entry to another
dispatch({ type: 'RESET_PROPS' });
dispatch({
type: 'SET_LAYOUT_DATA',
formattedContentTypeLayout: formatLayoutRef.current(
currentContentTypeLayout,
currentContentTypeSchema.attributes
),
});
}, [currentContentTypeLayout, currentContentTypeSchema.attributes]);
2019-09-16 17:47:43 +02:00
2019-10-30 14:47:12 +01:00
const { formattedContentTypeLayout } = reducerState.toJS();
2019-09-13 14:46:31 +02:00
// We can't use the getQueryParameters helper here because the search
// can contain 'redirectUrl' several times since we can navigate between documents
const redirectURL = search
.split('redirectUrl=')
.filter((_, index) => index !== 0)
.join('');
const redirectToPreviousPage = () => push(redirectURL);
2019-09-13 14:46:31 +02:00
2019-07-11 11:35:18 +02:00
return (
2019-10-29 19:26:42 +01:00
<EditViewProvider layout={currentContentTypeLayoutData}>
2019-10-30 19:06:40 +01:00
<EditViewDataManagerProvider
allLayoutData={allLayoutData}
redirectToPreviousPage={redirectToPreviousPage}
slug={slug}
>
<BackHeader onClick={() => redirectToPreviousPage()} />
<Container className="container-fluid">
2019-10-30 14:47:12 +01:00
<Header />
2019-07-11 16:53:00 +02:00
<div className="row">
2019-07-24 18:24:23 +02:00
<div className="col-md-12 col-lg-9">
{formattedContentTypeLayout.map((block, blockIndex) => {
if (isDynamicZone(block)) {
const {
0: {
0: { name },
},
} = block;
2019-08-09 13:23:39 +02:00
2019-10-29 19:26:42 +01:00
return <DynamicZone key={blockIndex} name={name} />;
}
2019-10-29 19:26:42 +01:00
return (
<FormWrapper key={blockIndex}>
{block.map((fieldsBlock, fieldsBlockIndex) => {
return (
<div className="row" key={fieldsBlockIndex}>
{fieldsBlock.map(({ name, size }, fieldIndex) => {
2019-10-30 19:06:40 +01:00
const isComponent =
getFieldType(name) === 'component';
if (isComponent) {
return (
<div className={`col-${size}`} key={name}>
COMPONENT: {name}
</div>
);
}
2019-10-29 19:26:42 +01:00
return (
<div className={`col-${size}`} key={name}>
2019-10-30 15:32:29 +01:00
<Inputs
2019-10-29 19:26:42 +01:00
autoFocus={
blockIndex === 0 &&
fieldsBlockIndex === 0 &&
fieldIndex === 0
}
keys={name}
layout={currentContentTypeLayoutData}
name={name}
onChange={() => {}}
2019-10-30 15:32:29 +01:00
/>
2019-10-29 19:26:42 +01:00
</div>
);
})}
</div>
);
})}
</FormWrapper>
);
})}
2019-07-12 14:15:56 +02:00
</div>
2019-07-12 14:15:56 +02:00
<div className="col-md-12 col-lg-3">
{currentContentTypeLayoutRelations.length > 0 && (
2019-07-12 14:15:56 +02:00
<SubWrapper
2019-07-29 17:11:53 +02:00
style={{ padding: '0 20px 1px', marginBottom: '26px' }}
2019-07-12 14:15:56 +02:00
>
2019-07-22 11:41:27 +02:00
<div style={{ paddingTop: '22px' }}>
{currentContentTypeLayoutRelations.map(relationName => {
2019-10-30 14:47:12 +01:00
const relation = get(
currentContentTypeLayoutData,
['schema', 'attributes', relationName],
{}
);
const relationMetas = get(
currentContentTypeLayoutData,
['metadatas', relationName, 'edit'],
{}
);
2019-07-16 18:53:41 +02:00
2019-10-30 14:47:12 +01:00
return (
<SelectWrapper
{...relation}
{...relationMetas}
key={relationName}
name={relationName}
relationsType={relation.relationType}
/>
);
2019-07-16 18:53:41 +02:00
})}
2019-07-15 13:00:31 +02:00
</div>
2019-07-12 14:15:56 +02:00
</SubWrapper>
)}
2019-07-11 16:53:00 +02:00
<LinkWrapper>
<ul>
<LiLink
message={{
id: 'app.links.configure-view',
2019-07-11 16:53:00 +02:00
}}
icon="layout"
key={`${pluginId}.link`}
2019-10-24 17:08:52 +02:00
// url={`/plugins/${pluginId}/ctm-configurations/edit-settings/content-types/${slug}${`?source=${source}`}`}
url={`ctm-configurations/edit-settings/content-types${`?source=${source}`}`}
2019-07-11 16:53:00 +02:00
onClick={() => {
// emitEvent('willEditContentTypeLayoutFromEditView');
2019-07-11 16:53:00 +02:00
}}
/>
2019-08-22 17:15:15 +02:00
{getInjectedComponents(
'right.links',
plugins,
currentEnvironment,
slug,
source,
emitEvent
)}
2019-07-11 16:53:00 +02:00
</ul>
</LinkWrapper>
</div>
</div>
</Container>
</EditViewDataManagerProvider>
2019-07-17 17:39:43 +02:00
</EditViewProvider>
2019-07-11 11:35:18 +02:00
);
};
EditView.defaultProps = {
currentEnvironment: 'production',
emitEvent: () => {},
plugins: {},
};
2019-07-10 09:31:26 +02:00
2019-07-11 11:35:18 +02:00
EditView.propTypes = {
currentEnvironment: PropTypes.string,
emitEvent: PropTypes.func,
layouts: PropTypes.object.isRequired,
2019-10-24 17:08:52 +02:00
slug: PropTypes.string.isRequired,
2019-07-11 16:53:00 +02:00
plugins: PropTypes.object,
2019-07-11 11:35:18 +02:00
};
export { EditView };
2019-07-11 11:35:18 +02:00
export default memo(EditView);