Remove useEditView hook which is not needed anymore

Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
soupette 2020-10-29 12:19:21 +01:00
parent e0eac0f4e9
commit 237f5b4deb
15 changed files with 244 additions and 282 deletions

View File

@ -72,6 +72,10 @@
},
"address": {
"model": "address"
},
"admin_user": {
"plugin": "admin",
"model": "user"
}
}
}

View File

@ -19,7 +19,6 @@ import { connect, select, styles } from './utils';
function SelectWrapper({
description,
displayNavigationLink,
editable,
label,
isCreatingEntry,
@ -163,7 +162,7 @@ function SelectWrapper({
return null;
}
if (!displayNavigationLink) {
if (!queryInfos.shouldDisplayRelationLink) {
return null;
}
@ -174,7 +173,7 @@ function SelectWrapper({
</FormattedMessage>
</Link>
);
}, [displayNavigationLink, pathname, to, value]);
}, [queryInfos.shouldDisplayRelationLink, pathname, to, value]);
const Component = isSingle ? SelectOne : SelectMany;
const associationsLength = isArray(value) ? value.length : 0;
@ -225,7 +224,7 @@ function SelectWrapper({
addRelation({ target: { name, value } });
}}
components={{ ClearIndicator, DropdownIndicator, IndicatorSeparator, Option }}
displayNavigationLink={displayNavigationLink}
displayNavigationLink={queryInfos.shouldDisplayRelationLink}
id={name}
isDisabled={isDisabled}
isLoading={isLoading}
@ -269,7 +268,6 @@ SelectWrapper.defaultProps = {
};
SelectWrapper.propTypes = {
displayNavigationLink: PropTypes.bool.isRequired,
editable: PropTypes.bool,
description: PropTypes.string,
label: PropTypes.string,
@ -285,6 +283,7 @@ SelectWrapper.propTypes = {
containsKey: PropTypes.string.isRequired,
defaultParams: PropTypes.object,
endPoint: PropTypes.string.isRequired,
shouldDisplayRelationLink: PropTypes.bool.isRequired,
}).isRequired,
};

View File

@ -1,9 +1,7 @@
import { useMemo } from 'react';
import { get } from 'lodash';
import useDataManager from '../../../hooks/useDataManager';
import useEditView from '../../../hooks/useEditView';
function useSelect({ isUserAllowedToEditField, isUserAllowedToReadField, name, targetModel }) {
function useSelect({ isUserAllowedToEditField, isUserAllowedToReadField, name }) {
const {
isCreatingEntry,
createActionAllowedFields,
@ -11,16 +9,6 @@ function useSelect({ isUserAllowedToEditField, isUserAllowedToReadField, name, t
updateActionAllowedFields,
} = useDataManager();
// TODO important! remove models dependency from the useEditView hook,
// This info should be handle in the layout?
const { models } = useEditView();
const displayNavigationLink = useMemo(() => {
const targetModelSchema = models.find(obj => obj.uid === targetModel);
return get(targetModelSchema, 'isDisplayed', false);
}, [targetModel, models]);
const isFieldAllowed = useMemo(() => {
if (isUserAllowedToEditField === true) {
return true;
@ -48,7 +36,6 @@ function useSelect({ isUserAllowedToEditField, isUserAllowedToReadField, name, t
}, [isCreatingEntry, isUserAllowedToReadField, name, readActionAllowedFields]);
return {
displayNavigationLink,
isCreatingEntry,
isFieldAllowed,
isFieldReadable,

View File

@ -11,13 +11,7 @@ import { getTrad } from '../../../utils';
import { DeleteButton } from '../components';
import { connect, select } from './utils';
const DeleteLink = ({
canDelete,
isCreatingEntry,
onDelete,
onDeleteSucceeded,
trackerProperty,
}) => {
const DeleteLink = ({ isCreatingEntry, onDelete, onDeleteSucceeded, trackerProperty }) => {
const [showWarningDelete, setWarningDelete] = useState(false);
const [didDeleteEntry, setDidDeleteEntry] = useState(false);
const [isModalConfirmButtonLoading, setIsModalConfirmButtonLoading] = useState(false);
@ -57,7 +51,7 @@ const DeleteLink = ({
}
};
if (isCreatingEntry || !canDelete) {
if (isCreatingEntry) {
return null;
}
@ -89,7 +83,6 @@ const DeleteLink = ({
};
DeleteLink.propTypes = {
canDelete: PropTypes.bool.isRequired,
isCreatingEntry: PropTypes.bool.isRequired,
onDelete: PropTypes.func.isRequired,
onDeleteSucceeded: PropTypes.func.isRequired,

View File

@ -1,12 +1,8 @@
import { isEmpty } from 'lodash';
import useDataManager from '../../../../hooks/useDataManager';
import useEditView from '../../../../hooks/useEditView';
function useSelect() {
const { hasDraftAndPublish, modifiedData } = useDataManager();
const {
allowedActions: { canDelete },
} = useEditView();
let trackerProperty = {};
@ -17,7 +13,6 @@ function useSelect() {
}
return {
canDelete,
hasDraftAndPublish,
trackerProperty,
};

View File

@ -19,9 +19,7 @@ const primaryButtonObject = {
};
const Header = ({
canUpdate,
canCreate,
canPublish,
allowedActions: { canUpdate, canCreate, canPublish },
componentLayouts,
initialData,
isCreatingEntry,
@ -237,9 +235,11 @@ const Header = ({
};
Header.propTypes = {
canUpdate: PropTypes.bool.isRequired,
canCreate: PropTypes.bool.isRequired,
canPublish: PropTypes.bool.isRequired,
allowedActions: PropTypes.shape({
canUpdate: PropTypes.bool.isRequired,
canCreate: PropTypes.bool.isRequired,
canPublish: PropTypes.bool.isRequired,
}).isRequired,
componentLayouts: PropTypes.object.isRequired,
initialData: PropTypes.object.isRequired,
isCreatingEntry: PropTypes.bool.isRequired,

View File

@ -1,5 +1,4 @@
import useDataManager from '../../../../hooks/useDataManager';
import useEditView from '../../../../hooks/useEditView';
function useSelect() {
const {
@ -14,14 +13,8 @@ function useSelect() {
onPublish,
onUnpublish,
} = useDataManager();
const {
allowedActions: { canUpdate, canCreate, canPublish },
} = useEditView();
return {
canUpdate,
canCreate,
canPublish,
componentLayouts: allLayoutData.components,
initialData,
isCreatingEntry,

View File

@ -23,7 +23,6 @@ import { useFetchContentTypeLayout } from '../../hooks';
import { generatePermissionsObject, getInjectedComponents } from '../../utils';
import CollectionTypeWrapper from '../CollectionTypeWrapper';
import EditViewDataManagerProvider from '../EditViewDataManagerProvider';
import EditViewProvider from '../EditViewProvider';
import SingleTypeWrapper from '../SingleTypeWrapper';
import Header from './Header';
import { createAttributesLayout, getFieldsActionMatchingPermissions } from './utils';
@ -34,7 +33,7 @@ import InformationCard from './InformationCard';
/* eslint-disable react/no-array-index-key */
// TODO check needed props
const EditView = ({ components, currentEnvironment, models, isSingleType, plugins, slug }) => {
const EditView = ({ currentEnvironment, isSingleType, plugins, slug }) => {
const { isLoading, layout } = useFetchContentTypeLayout(slug);
const { goBack } = useHistory();
// Legacy to remove for the configurations
@ -101,210 +100,195 @@ const EditView = ({ components, currentEnvironment, models, isSingleType, plugin
}
return (
<EditViewProvider
allowedActions={allowedActions}
allLayoutData={layout}
components={components}
isSingleType={isSingleType}
layout={currentContentTypeLayoutData}
// TODO: check if still needed
models={models}
>
<ContentTypeLayoutContext.Provider value={layout}>
<DataManagementWrapper allLayoutData={layout} from={from} slug={slug}>
{({
componentsDataStructure,
contentTypeDataStructure,
data,
isCreatingEntry,
isLoadingForData,
onDelete,
onDeleteSucceeded,
onPost,
onPublish,
onPut,
onUnpublish,
status,
}) => {
return (
<EditViewDataManagerProvider
allowedActions={allowedActions}
allLayoutData={layout}
createActionAllowedFields={createActionAllowedFields}
componentsDataStructure={componentsDataStructure}
contentTypeDataStructure={contentTypeDataStructure}
from={from}
initialValues={data}
isCreatingEntry={isCreatingEntry}
isLoadingForData={isLoadingForData}
isSingleType={isSingleType}
onPost={onPost}
onPublish={onPublish}
onPut={onPut}
onUnpublish={onUnpublish}
readActionAllowedFields={readActionAllowedFields}
// TODO check if needed
redirectToPreviousPage={goBack}
slug={slug}
status={status}
updateActionAllowedFields={updateActionAllowedFields}
>
<BackHeader onClick={goBack} />
<Container className="container-fluid">
<Header />
<div className="row" style={{ paddingTop: 3 }}>
<div className="col-md-12 col-lg-9" style={{ marginBottom: 13 }}>
{formattedContentTypeLayout.map((block, blockIndex) => {
if (isDynamicZone(block)) {
const {
0: {
0: { name, fieldSchema, metadatas },
},
} = block;
return (
<DynamicZone
key={blockIndex}
name={name}
fieldSchema={fieldSchema}
metadatas={metadatas}
/>
);
}
<ContentTypeLayoutContext.Provider value={layout}>
<DataManagementWrapper allLayoutData={layout} from={from} slug={slug}>
{({
componentsDataStructure,
contentTypeDataStructure,
data,
isCreatingEntry,
isLoadingForData,
onDelete,
onDeleteSucceeded,
onPost,
onPublish,
onPut,
onUnpublish,
status,
}) => {
return (
<EditViewDataManagerProvider
allowedActions={allowedActions}
allLayoutData={layout}
createActionAllowedFields={createActionAllowedFields}
componentsDataStructure={componentsDataStructure}
contentTypeDataStructure={contentTypeDataStructure}
from={from}
initialValues={data}
isCreatingEntry={isCreatingEntry}
isLoadingForData={isLoadingForData}
isSingleType={isSingleType}
onPost={onPost}
onPublish={onPublish}
onPut={onPut}
onUnpublish={onUnpublish}
readActionAllowedFields={readActionAllowedFields}
// TODO check if needed
redirectToPreviousPage={goBack}
slug={slug}
status={status}
updateActionAllowedFields={updateActionAllowedFields}
>
<BackHeader onClick={goBack} />
<Container className="container-fluid">
<Header allowedActions={allowedActions} />
<div className="row" style={{ paddingTop: 3 }}>
<div className="col-md-12 col-lg-9" style={{ marginBottom: 13 }}>
{formattedContentTypeLayout.map((block, blockIndex) => {
if (isDynamicZone(block)) {
const {
0: {
0: { name, fieldSchema, metadatas },
},
} = block;
return (
<FormWrapper key={blockIndex}>
{block.map((fieldsBlock, fieldsBlockIndex) => {
return (
<div className="row" key={fieldsBlockIndex}>
{fieldsBlock.map(
({ name, size, fieldSchema, metadatas }, fieldIndex) => {
const isComponent = fieldSchema.type === 'component';
<DynamicZone
key={blockIndex}
name={name}
fieldSchema={fieldSchema}
metadatas={metadatas}
/>
);
}
if (isComponent) {
const {
component,
max,
min,
repeatable = false,
} = fieldSchema;
const componentUid = fieldSchema.component;
return (
<FormWrapper key={blockIndex}>
{block.map((fieldsBlock, fieldsBlockIndex) => {
return (
<div className="row" key={fieldsBlockIndex}>
{fieldsBlock.map(
({ name, size, fieldSchema, metadatas }, fieldIndex) => {
const isComponent = fieldSchema.type === 'component';
return (
<FieldComponent
key={componentUid}
componentUid={component}
isRepeatable={repeatable}
label={metadatas.label}
max={max}
min={min}
name={name}
/>
);
}
if (isComponent) {
const {
component,
max,
min,
repeatable = false,
} = fieldSchema;
const componentUid = fieldSchema.component;
return (
<div className={`col-${size}`} key={name}>
<Inputs
autoFocus={
blockIndex === 0 &&
fieldsBlockIndex === 0 &&
fieldIndex === 0
}
fieldSchema={fieldSchema}
keys={name}
metadatas={metadatas}
/>
</div>
<FieldComponent
key={componentUid}
componentUid={component}
isRepeatable={repeatable}
label={metadatas.label}
max={max}
min={min}
name={name}
/>
);
}
)}
</div>
);
})}
</FormWrapper>
);
})}
</div>
<div className="col-md-12 col-lg-3">
<InformationCard />
<Padded size="smd" top />
{currentContentTypeLayoutData.layouts.editRelations.length > 0 && (
<SubWrapper style={{ padding: '0 20px 1px', marginBottom: '25px' }}>
<div style={{ paddingTop: '22px' }}>
{currentContentTypeLayoutData.layouts.editRelations.map(
({ name, fieldSchema, metadatas, queryInfos }) => {
return (
<SelectWrapper
{...fieldSchema}
{...metadatas}
queryInfos={queryInfos}
key={name}
name={name}
relationsType={fieldSchema.relationType}
/>
);
}
)}
</div>
</SubWrapper>
)}
<LinkWrapper>
<ul>
<CheckPermissions permissions={configurationPermissions}>
<LiLink
message={{
id: 'app.links.configure-view',
}}
icon="layout"
url={configurationsURL}
onClick={() => {
// emitEvent('willEditContentTypeLayoutFromEditView');
}}
/>
</CheckPermissions>
{getInjectedComponents(
'editView',
'right.links',
plugins,
currentEnvironment,
slug
)}
{allowedActions.canDelete && (
<DeleteLink
isCreatingEntry={isCreatingEntry}
onDelete={onDelete}
onDeleteSucceeded={onDeleteSucceeded}
/>
)}
</ul>
</LinkWrapper>
</div>
return (
<div className={`col-${size}`} key={name}>
<Inputs
autoFocus={
blockIndex === 0 &&
fieldsBlockIndex === 0 &&
fieldIndex === 0
}
fieldSchema={fieldSchema}
keys={name}
metadatas={metadatas}
/>
</div>
);
}
)}
</div>
);
})}
</FormWrapper>
);
})}
</div>
</Container>
</EditViewDataManagerProvider>
);
}}
</DataManagementWrapper>
</ContentTypeLayoutContext.Provider>
</EditViewProvider>
<div className="col-md-12 col-lg-3">
<InformationCard />
<Padded size="smd" top />
{currentContentTypeLayoutData.layouts.editRelations.length > 0 && (
<SubWrapper style={{ padding: '0 20px 1px', marginBottom: '25px' }}>
<div style={{ paddingTop: '22px' }}>
{currentContentTypeLayoutData.layouts.editRelations.map(
({ name, fieldSchema, metadatas, queryInfos }) => {
return (
<SelectWrapper
{...fieldSchema}
{...metadatas}
queryInfos={queryInfos}
key={name}
name={name}
relationsType={fieldSchema.relationType}
/>
);
}
)}
</div>
</SubWrapper>
)}
<LinkWrapper>
<ul>
<CheckPermissions permissions={configurationPermissions}>
<LiLink
message={{
id: 'app.links.configure-view',
}}
icon="layout"
url={configurationsURL}
onClick={() => {
// emitEvent('willEditContentTypeLayoutFromEditView');
}}
/>
</CheckPermissions>
{getInjectedComponents(
'editView',
'right.links',
plugins,
currentEnvironment,
slug
)}
{allowedActions.canDelete && (
<DeleteLink
isCreatingEntry={isCreatingEntry}
onDelete={onDelete}
onDeleteSucceeded={onDeleteSucceeded}
/>
)}
</ul>
</LinkWrapper>
</div>
</div>
</Container>
</EditViewDataManagerProvider>
);
}}
</DataManagementWrapper>
</ContentTypeLayoutContext.Provider>
);
};
EditView.defaultProps = {
// TODO
currentEnvironment: 'production',
emitEvent: () => {},
plugins: {},
isSingleType: false,
};
EditView.propTypes = {
components: PropTypes.array.isRequired,
currentEnvironment: PropTypes.string,
emitEvent: PropTypes.func,
isSingleType: PropTypes.bool,
models: PropTypes.array.isRequired,
plugins: PropTypes.object,
slug: PropTypes.string.isRequired,
};

View File

@ -5,8 +5,7 @@ import { initialState } from './reducer';
/**
* Direct selector to the main state domain
*/
const selectMainDomain = () => state =>
state.get(`${pluginId}_main`) || initialState;
const selectMainDomain = () => state => state.get(`${pluginId}_main`) || initialState;
/**
* Other specific selectors
@ -17,12 +16,16 @@ const selectMainDomain = () => state =>
*/
const makeSelectMain = () =>
createSelector(
selectMainDomain(),
substate => {
return substate.toJS();
}
);
createSelector(selectMainDomain(), substate => {
return substate.toJS();
});
const makeSelectModels = () =>
createSelector(selectMainDomain(), substate => {
const allModels = substate.get('models').toJS();
return allModels.filter(model => model.isDisplayed === true).map(({ uid }) => uid);
});
export default makeSelectMain;
export { selectMainDomain };
export { makeSelectModels, selectMainDomain };

View File

@ -1,5 +0,0 @@
import { createContext } from 'react';
const EditViewContext = createContext();
export default EditViewContext;

View File

@ -1,5 +1,4 @@
export { default as ContentTypeLayoutContext } from './ContentTypeLayout';
export { default as EditViewContext } from './EditView';
export { default as EditViewDataManagerContext } from './EditViewDataManager';
export { default as LayoutDndContext } from './LayoutDnd';
export { default as ListViewContext } from './ListView';

View File

@ -1,7 +1,6 @@
export { default as useContentTypeLayout } from './useContentTypeLayout';
export { default as useFetchContentTypeLayout } from './useFetchContentTypeLayout';
export { default as useDataManager } from './useDataManager';
export { default as useEditView } from './useEditView';
export { default as useLayoutDnd } from './useLayoutDnd';
export { default as useListView } from './useListView';
export { default as useWysiwyg } from './useWysiwyg';

View File

@ -1,6 +0,0 @@
import { useContext } from 'react';
import EditViewContext from '../contexts/EditView';
const useEditView = () => useContext(EditViewContext);
export default useEditView;

View File

@ -1,31 +1,38 @@
import { useCallback, useEffect, useReducer } from 'react';
import { useCallback, useEffect, useMemo, useReducer } from 'react';
import { useSelector } from 'react-redux';
import { request } from 'strapi-helper-plugin';
import formatLayouts from './utils/formatLayouts';
import reducer, { initialState } from './reducer';
import { makeSelectModels } from '../../containers/Main/selectors';
const useFetchContentTypeLayout = contentTypeUID => {
const [{ error, isLoading, layout }, dispatch] = useReducer(reducer, initialState);
const modelsSelector = useMemo(makeSelectModels, []);
const models = useSelector(state => modelsSelector(state), []);
const getData = useCallback(async (uid, abortSignal = false) => {
let signal = abortSignal || new AbortController().signal;
const getData = useCallback(
async (uid, abortSignal = false) => {
let signal = abortSignal || new AbortController().signal;
dispatch({ type: 'GET_DATA' });
dispatch({ type: 'GET_DATA' });
try {
const { data } = await request(`/content-manager/content-types/${uid}`, {
method: 'GET',
signal,
});
try {
const { data } = await request(`/content-manager/content-types/${uid}`, {
method: 'GET',
signal,
});
dispatch({
type: 'GET_DATA_SUCCEEDED',
data: formatLayouts(data),
});
} catch (error) {
console.error(error);
dispatch({ type: 'GET_DATA_ERROR', error });
}
}, []);
dispatch({
type: 'GET_DATA_SUCCEEDED',
data: formatLayouts(data, models),
});
} catch (error) {
console.error(error);
dispatch({ type: 'GET_DATA_ERROR', error });
}
},
[models]
);
useEffect(() => {
const abortController = new AbortController();

View File

@ -1,7 +1,7 @@
import { get, set } from 'lodash';
import pluginId from '../../../pluginId';
const formatLayoutWithMetas = (obj, ctUid) => {
const formatLayoutWithMetas = (obj, ctUid, models) => {
const formatted = obj.layouts.edit.reduce((acc, current) => {
const row = current.map(attribute => {
const fieldSchema = get(obj, ['schema', 'attributes', attribute.name], {});
@ -14,8 +14,8 @@ const formatLayoutWithMetas = (obj, ctUid) => {
if (fieldSchema.type === 'relation') {
const queryInfos = ctUid
? generateRelationQueryInfosForComponents(obj, attribute.name, ctUid)
: generateRelationQueryInfos(obj, attribute.name);
? generateRelationQueryInfosForComponents(obj, attribute.name, ctUid, models)
: generateRelationQueryInfos(obj, attribute.name, models);
set(data, 'queryInfos', queryInfos);
}
@ -31,23 +31,28 @@ const formatLayoutWithMetas = (obj, ctUid) => {
return formatted;
};
const generateRelationQueryInfos = (obj, fieldName) => {
const generateRelationQueryInfos = (obj, fieldName, models) => {
const uid = obj.uid;
const endPoint = `/${pluginId}/explorer/${uid}/relation-list/${fieldName}`;
const mainField = get(obj, ['metadatas', fieldName, 'edit', 'mainField'], '');
const targetModel = get(obj, ['schema', 'attributes', fieldName, 'targetModel'], '');
const shouldDisplayRelationLink = models.indexOf(targetModel) !== -1;
const queryInfos = {
endPoint,
containsKey: `${mainField}_contains`,
defaultParams: {},
shouldDisplayRelationLink,
};
return queryInfos;
};
const generateRelationQueryInfosForComponents = (obj, fieldName, ctUid) => {
const generateRelationQueryInfosForComponents = (obj, fieldName, ctUid, models) => {
const endPoint = `/${pluginId}/explorer/${ctUid}/relation-list/${fieldName}`;
const mainField = get(obj, ['metadatas', fieldName, 'edit', 'mainField'], '');
const targetModel = get(obj, ['schema', 'attributes', fieldName, 'targetModel'], '');
const shouldDisplayRelationLink = models.indexOf(targetModel) !== -1;
const queryInfos = {
endPoint,
@ -55,19 +60,20 @@ const generateRelationQueryInfosForComponents = (obj, fieldName, ctUid) => {
defaultParams: {
_component: obj.uid,
},
shouldDisplayRelationLink,
};
return queryInfos;
};
// editRelations is an array of strings...
const formatEditRelationsLayoutWithMetas = obj => {
const formatEditRelationsLayoutWithMetas = (obj, models) => {
const formatted = obj.layouts.editRelations.reduce((acc, current) => {
const fieldSchema = get(obj, ['schema', 'attributes', current], {});
const metadatas = get(obj, ['metadatas', current, 'edit'], {});
const size = 6;
const queryInfos = generateRelationQueryInfos(obj, current);
const queryInfos = generateRelationQueryInfos(obj, current, models);
acc.push({
name: current,
@ -83,16 +89,20 @@ const formatEditRelationsLayoutWithMetas = obj => {
return formatted;
};
const formatLayouts = data => {
const formattedCTEditLayout = formatLayoutWithMetas(data.contentType);
const formatLayouts = (data, models) => {
const formattedCTEditLayout = formatLayoutWithMetas(data.contentType, models);
const ctUid = data.contentType.uid;
const formattedEditRelationsLayout = formatEditRelationsLayoutWithMetas(data.contentType);
const formattedEditRelationsLayout = formatEditRelationsLayoutWithMetas(data.contentType, models);
set(data, ['contentType', 'layouts', 'edit'], formattedCTEditLayout);
set(data, ['contentType', 'layouts', 'editRelations'], formattedEditRelationsLayout);
Object.keys(data.components).forEach(compoUID => {
const formattedCompoEditLayout = formatLayoutWithMetas(data.components[compoUID], ctUid);
const formattedCompoEditLayout = formatLayoutWithMetas(
data.components[compoUID],
ctUid,
models
);
set(data, ['components', compoUID, 'layouts', 'edit'], formattedCompoEditLayout);
});