mirror of
https://github.com/strapi/strapi.git
synced 2025-09-08 08:08:18 +00:00
Merge pull request #9760 from strapi/i18n/cm-fix-relations
[I18n] CM fix navigation between localised content types
This commit is contained in:
commit
0e336b4e31
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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} </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,
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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}
|
||||
/>
|
||||
|
@ -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 });
|
||||
|
@ -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: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user