Merge pull request #9760 from strapi/i18n/cm-fix-relations

[I18n] CM fix navigation between localised content types
This commit is contained in:
cyril lopez 2021-03-18 11:13:17 +01:00 committed by GitHub
commit 0e336b4e31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 68 additions and 10 deletions

View File

@ -18,6 +18,7 @@ function ListItem({
mainField,
moveRelation,
onRemove,
searchToPersist,
targetModel,
}) {
const to = `/plugins/${pluginId}/collectionType/${targetModel}/${data.id}`;
@ -72,6 +73,7 @@ function ListItem({
data={data}
to={to}
isDisabled={isDisabled}
searchToPersist={searchToPersist}
/>
</Li>
);
@ -81,6 +83,7 @@ ListItem.defaultProps = {
findRelation: () => {},
moveRelation: () => {},
onRemove: () => {},
searchToPersist: null,
targetModel: '',
};
@ -97,6 +100,7 @@ ListItem.propTypes = {
}).isRequired,
moveRelation: PropTypes.func,
onRemove: PropTypes.func,
searchToPersist: PropTypes.string,
targetModel: PropTypes.string,
};

View File

@ -19,6 +19,7 @@ const Relation = ({
isDragging,
mainField,
onRemove,
searchToPersist,
to,
}) => {
const { formatMessage } = useIntl();
@ -61,7 +62,10 @@ const Relation = ({
</div>
)}
{displayNavigationLink ? (
<Link to={{ pathname: to, state: { from: pathname } }} title={title}>
<Link
to={{ pathname: to, state: { from: pathname }, search: searchToPersist }}
title={title}
>
<Span>{formattedValue}&nbsp;</Span>
</Link>
) : (
@ -78,6 +82,7 @@ const Relation = ({
Relation.defaultProps = {
isDragging: false,
onRemove: () => {},
searchToPersist: null,
to: '',
};
@ -94,6 +99,7 @@ Relation.propTypes = {
}).isRequired,
}).isRequired,
onRemove: PropTypes.func,
searchToPersist: PropTypes.string,
to: PropTypes.string,
};

View File

@ -23,6 +23,7 @@ function SelectMany({
onRemove,
options,
placeholder,
searchToPersist,
styles,
targetModel,
value,
@ -109,6 +110,7 @@ function SelectMany({
onRemove(`${name}.${index}`);
}
}}
searchToPersist={searchToPersist}
targetModel={targetModel}
/>
))}
@ -123,6 +125,7 @@ function SelectMany({
SelectMany.defaultProps = {
components: {},
move: () => {},
searchToPersist: null,
value: null,
};
@ -147,6 +150,7 @@ SelectMany.propTypes = {
onRemove: PropTypes.func.isRequired,
options: PropTypes.array.isRequired,
placeholder: PropTypes.node.isRequired,
searchToPersist: PropTypes.string,
styles: PropTypes.object.isRequired,
targetModel: PropTypes.string.isRequired,
value: PropTypes.array,

View File

@ -2,14 +2,16 @@ import React, { useCallback, useState, useEffect, useMemo, memo } from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage, useIntl } from 'react-intl';
import { Link, useLocation } from 'react-router-dom';
import { findIndex, get, isArray, isEmpty } from 'lodash';
import { findIndex, get, isArray, isEmpty, set } from 'lodash';
import {
LabelIconWrapper,
NotAllowedInput,
request,
useContentManagerEditViewDataManager,
useQueryParams,
} from 'strapi-helper-plugin';
import { Flex, Text, Padded } from '@buffetjs/core';
import { stringify } from 'qs';
import pluginId from '../../pluginId';
import SelectOne from '../SelectOne';
import SelectMany from '../SelectMany';
@ -25,6 +27,22 @@ const initialPaginationState = {
_limit: 20,
_start: 0,
};
const buildParams = (query, paramsToKeep) => {
if (!paramsToKeep) {
return {};
}
return paramsToKeep.reduce((acc, current) => {
const value = get(query, current, null);
if (value) {
set(acc, current, value);
}
return acc;
}, {});
};
function SelectWrapper({
description,
editable,
@ -41,6 +59,7 @@ function SelectWrapper({
queryInfos,
}) {
const { formatMessage } = useIntl();
const [{ query }] = useQueryParams();
// Disable the input in case of a polymorphic relation
const isMorph = useMemo(() => relationType.toLowerCase().includes('morph'), [relationType]);
const {
@ -74,7 +93,13 @@ function SelectWrapper({
});
}, [options, value]);
const { endPoint, containsKey, defaultParams, shouldDisplayRelationLink } = queryInfos;
const {
endPoint,
containsKey,
defaultParams,
shouldDisplayRelationLink,
paramsToKeep,
} = queryInfos;
const isSingle = ['oneWay', 'oneToOne', 'manyToOne', 'oneToManyMorph', 'oneToOneMorph'].includes(
relationType
@ -206,6 +231,8 @@ function SelectWrapper({
const to = `/plugins/${pluginId}/collectionType/${targetModel}/${value ? value.id : null}`;
const searchToPersist = stringify(buildParams(query, paramsToKeep), { encode: false });
const link = useMemo(() => {
if (!value) {
return null;
@ -216,13 +243,13 @@ function SelectWrapper({
}
return (
<Link to={{ pathname: to, state: { from: pathname } }}>
<Link to={{ pathname: to, state: { from: pathname }, search: searchToPersist }}>
<FormattedMessage id="content-manager.containers.Edit.seeDetails">
{msg => <A color="mediumBlue">{msg}</A>}
</FormattedMessage>
</Link>
);
}, [shouldDisplayRelationLink, pathname, to, value]);
}, [shouldDisplayRelationLink, pathname, to, value, searchToPersist]);
const Component = isSingle ? SelectOne : SelectMany;
const associationsLength = isArray(value) ? value.length : 0;
@ -305,6 +332,7 @@ function SelectWrapper({
placeholder
)
}
searchToPersist={searchToPersist}
styles={styles}
targetModel={targetModel}
value={value}
@ -348,11 +376,12 @@ SelectWrapper.propTypes = {
placeholder: PropTypes.string,
relationType: PropTypes.string.isRequired,
targetModel: PropTypes.string.isRequired,
queryInfos: PropTypes.exact({
queryInfos: PropTypes.shape({
containsKey: PropTypes.string.isRequired,
defaultParams: PropTypes.object,
endPoint: PropTypes.string.isRequired,
shouldDisplayRelationLink: PropTypes.bool.isRequired,
paramsToKeep: PropTypes.array,
}).isRequired,
};

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { useMemo } from 'react';
import get from 'lodash/get';
import { useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';
@ -16,11 +16,19 @@ const CMEditViewInjectedComponents = () => {
const id = get(params, 'id', null);
const currentEntityId = id === 'create' ? null : id;
const currentLocale = get(query, 'plugins.i18n.locale', false);
const defaultLocale = locales.find(loc => loc.isDefault);
const currentLocale = get(query, 'plugins.i18n.locale', defaultLocale.code);
const hasI18nEnabled = get(layout, ['pluginOptions', 'i18n', 'localized'], false);
const hasDraftAndPublishEnabled = get(layout, ['options', 'draftAndPublish'], false);
const defaultQuery = useMemo(() => {
if (!query) {
return { plugins: { i18n: { locale: currentLocale } } };
}
return query;
}, [query, currentLocale]);
if (!hasI18nEnabled) {
return null;
}
@ -42,7 +50,7 @@ const CMEditViewInjectedComponents = () => {
createPermissions={createPermissions}
hasDraftAndPublishEnabled={hasDraftAndPublishEnabled}
localizations={localizations}
query={query}
query={defaultQuery}
readPermissions={readPermissions}
slug={slug}
/>

View File

@ -18,6 +18,7 @@ const enhanceRelationLayout = (layout, locale) =>
queryInfos = {
...queryInfos,
defaultParams: { ...queryInfos.defaultParams, _locale: locale },
paramsToKeep: ['plugins.i18n.locale'],
};
}
@ -79,6 +80,7 @@ const enhanceComponentLayoutForRelations = (layout, locale) =>
const queryInfos = {
...field.queryInfos,
defaultParams: { ...field.queryInfos.defaultParams, _locale: locale },
paramsToKeep: ['plugins.i18n.locale'],
};
acc.push({ ...field, queryInfos });

View File

@ -107,6 +107,7 @@ describe('i18n | Middlewares | extendCMEditViewLayoutMiddleware', () => {
queryInfos: {
test: true,
defaultParams: {},
paramsToKeep: ['plugins.i18n.locale'],
},
size: 6,
targetModelPluginOptions: {},
@ -143,6 +144,7 @@ describe('i18n | Middlewares | extendCMEditViewLayoutMiddleware', () => {
queryInfos: {
test: true,
defaultParams: {},
paramsToKeep: ['plugins.i18n.locale'],
},
size: 6,
targetModelPluginOptions: {},
@ -305,6 +307,7 @@ describe('i18n | Middlewares | extendCMEditViewLayoutMiddleware', () => {
targetModelPluginOptions: { i18n: { localized: true } },
queryInfos: {
defaultParams: { test: true, _locale: 'en' },
paramsToKeep: ['plugins.i18n.locale'],
},
},
{
@ -326,6 +329,7 @@ describe('i18n | Middlewares | extendCMEditViewLayoutMiddleware', () => {
targetModelPluginOptions: { i18n: { localized: true } },
queryInfos: {
defaultParams: { test: true, _locale: 'en' },
paramsToKeep: ['plugins.i18n.locale'],
},
},
{
@ -515,6 +519,7 @@ describe('i18n | Middlewares | extendCMEditViewLayoutMiddleware', () => {
test: true,
_locale: 'en',
},
paramsToKeep: ['plugins.i18n.locale'],
},
size: 6,
targetModelPluginOptions: {