merge commit

This commit is contained in:
ronronscelestes 2021-10-12 14:52:20 +02:00
commit c1b61fa2a7
6 changed files with 100 additions and 53 deletions

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'styled-components'; import styled from 'styled-components';
import { get } from 'lodash'; import get from 'lodash/get';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import { Row } from '@strapi/parts/Row'; import { Row } from '@strapi/parts/Row';
import { Grid, GridItem } from '@strapi/parts/Grid'; import { Grid, GridItem } from '@strapi/parts/Grid';
@ -99,7 +99,7 @@ const Settings = ({ modifiedData, onChange, sortOptions }) => {
defaultMessage: defaultMessage:
'Note: You can override this value in the Collection Type settings page.', 'Note: You can override this value in the Collection Type settings page.',
})} })}
onChange={e => onChange({ target: { name: 'settings.pageSize', value: e } })} onChange={value => onChange({ target: { name: 'settings.pageSize', value } })}
name="settings.pageSize" name="settings.pageSize"
value={get(modifiedData, 'settings.pageSize', '')} value={get(modifiedData, 'settings.pageSize', '')}
> >
@ -116,7 +116,7 @@ const Settings = ({ modifiedData, onChange, sortOptions }) => {
id: 'content-manager.form.Input.defaultSort', id: 'content-manager.form.Input.defaultSort',
defaultMessage: 'Default sort attribute', defaultMessage: 'Default sort attribute',
})} })}
onChange={e => onChange({ target: { name: 'settings.defaultSortBy', value: e } })} onChange={value => onChange({ target: { name: 'settings.defaultSortBy', value } })}
name="settings.defaultSortBy" name="settings.defaultSortBy"
value={get(modifiedData, 'settings.defaultSortBy', '')} value={get(modifiedData, 'settings.defaultSortBy', '')}
> >
@ -133,7 +133,7 @@ const Settings = ({ modifiedData, onChange, sortOptions }) => {
id: 'content-manager.form.Input.sort.order', id: 'content-manager.form.Input.sort.order',
defaultMessage: 'Default sort order', defaultMessage: 'Default sort order',
})} })}
onChange={e => onChange({ target: { name: 'settings.defaultSortOrder', value: e } })} onChange={value => onChange({ target: { name: 'settings.defaultSortOrder', value } })}
name="settings.defaultSortOrder" name="settings.defaultSortOrder"
value={get(modifiedData, 'settings.defaultSortOrder', '')} value={get(modifiedData, 'settings.defaultSortOrder', '')}
> >

View File

@ -2,7 +2,10 @@ import React, { memo, useContext, useMemo, useReducer, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'styled-components'; import styled from 'styled-components';
import { useMutation } from 'react-query'; import { useMutation } from 'react-query';
import { isEqual, upperFirst, pick, get } from 'lodash'; import isEqual from 'lodash/isEqual';
import upperFirst from 'lodash/upperFirst';
import pick from 'lodash/pick';
import get from 'lodash/get';
import { stringify } from 'qs'; import { stringify } from 'qs';
import { useNotification, useTracking, ConfirmDialog } from '@strapi/helper-plugin'; import { useNotification, useTracking, ConfirmDialog } from '@strapi/helper-plugin';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
@ -27,6 +30,7 @@ import Settings from './components/Settings';
import DraggableCard from './components/DraggableCard'; import DraggableCard from './components/DraggableCard';
import init from './init'; import init from './init';
import reducer, { initialState } from './reducer'; import reducer, { initialState } from './reducer';
import { EXCLUDED_SORT_OPTIONS } from './utils/excludedSortOptions';
const Flex = styled(Box)` const Flex = styled(Box)`
flex: ${({ size }) => size}; flex: ${({ size }) => size};
@ -41,7 +45,7 @@ const SelectContainer = styled(Flex)`
max-width: ${200 / 16}rem; max-width: ${200 / 16}rem;
`; `;
const ListSettingsView = ({ layout, slug, updateLayout }) => { const ListSettingsView = ({ layout, slug }) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const { trackUsage } = useTracking(); const { trackUsage } = useTracking();
const pluginsQueryParams = usePluginsQueryParams(); const pluginsQueryParams = usePluginsQueryParams();
@ -74,14 +78,44 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
return get(modifiedData, ['layouts', 'list'], []); return get(modifiedData, ['layouts', 'list'], []);
}, [modifiedData]); }, [modifiedData]);
const excludedSortOptions = ['media', 'richtext', 'dynamiczone', 'relation', 'component', 'json']; const sortOptions = Object.entries(attributes).reduce((acc, cur) => {
const [name, { type }] = cur;
if (!EXCLUDED_SORT_OPTIONS.includes(type)) {
acc.push(name);
}
return acc;
}, []);
// const handleClickEditLabel = labelToEdit => {
// dispatch({
// type: 'SET_LABEL_TO_EDIT',
// labelToEdit,
// });
// toggleModalForm();
// };
// const handleClosed = () => {
// dispatch({
// type: 'UNSET_LABEL_TO_EDIT',
// });
// };
const handleChange = ({ target: { name, value } }) => {
dispatch({
type: 'ON_CHANGE',
keys: name,
value: name === 'settings.pageSize' ? parseInt(value, 10) : value,
});
};
const goBackUrl = () => { const goBackUrl = () => {
const { const {
settings: { pageSize, defaultSortBy, defaultSortOrder }, settings: { pageSize, defaultSortBy, defaultSortOrder },
kind, kind,
uid, uid,
} = modifiedData; } = initialData;
const sort = `${defaultSortBy}:${defaultSortOrder}`; const sort = `${defaultSortBy}:${defaultSortOrder}`;
const goBackSearch = `${stringify( const goBackSearch = `${stringify(
{ {
@ -95,15 +129,6 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
return `/content-manager/${kind}/${uid}?${goBackSearch}`; return `/content-manager/${kind}/${uid}?${goBackSearch}`;
}; };
const handleChange = ({ target: { name, value } }) => {
dispatch({
type: 'ON_CHANGE',
keys: name,
value: name === 'settings.pageSize' ? parseInt(value, 10) : value,
});
console.log('here');
};
const handleConfirm = async () => { const handleConfirm = async () => {
const body = pick(modifiedData, ['layouts', 'settings', 'metadatas']); const body = pick(modifiedData, ['layouts', 'settings', 'metadatas']);
submitMutation.mutateAsync(body); submitMutation.mutateAsync(body);
@ -138,23 +163,8 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
trackUsage('willSaveContentTypeLayout'); trackUsage('willSaveContentTypeLayout');
}; };
const sortOptions = Object.entries(attributes).reduce((acc, cur) => {
const [name, { type }] = cur;
if (!excludedSortOptions.includes(type)) {
acc.push(name);
}
return acc;
}, []);
const submitMutation = useMutation(body => putCMSettingsLV(body, slug), { const submitMutation = useMutation(body => putCMSettingsLV(body, slug), {
onSuccess: async ({ data: { data } }) => { onSuccess: async () => {
updateLayout(data);
dispatch({
type: 'SUBMIT_SUCCEEDED',
});
trackUsage('didEditListSettings'); trackUsage('didEditListSettings');
refetchData(); refetchData();
}, },
@ -164,7 +174,6 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
message: { id: 'notification.error' }, message: { id: 'notification.error' },
}); });
}, },
refetchActive: true,
}); });
const { isLoading: isSubmittingForm } = submitMutation; const { isLoading: isSubmittingForm } = submitMutation;
@ -257,7 +266,7 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<HeaderLayout <HeaderLayout
navigationAction={ navigationAction={
<Link startIcon={<BackIcon />} to={goBackUrl}> <Link startIcon={<BackIcon />} to={goBackUrl} id="go-back">
{formatMessage({ id: 'app.components.go-back', defaultMessage: 'Go back' })} {formatMessage({ id: 'app.components.go-back', defaultMessage: 'Go back' })}
</Link> </Link>
} }
@ -330,7 +339,12 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
</Stack> </Stack>
</ScrollableContainer> </ScrollableContainer>
<SelectContainer size="auto" paddingBottom={4}> <SelectContainer size="auto" paddingBottom={4}>
<Select onChange={e => handleAddField(e)} value="" placeholder="Add a field"> <Select
disabled={listRemainingFields.length <= 0}
onChange={e => handleAddField(e)}
value=""
placeholder="Add a field"
>
{listRemainingFields.map(field => ( {listRemainingFields.map(field => (
<Option value={field} key={field}> <Option value={field} key={field}>
{field} {field}
@ -479,13 +493,23 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
ListSettingsView.propTypes = { ListSettingsView.propTypes = {
layout: PropTypes.shape({ layout: PropTypes.shape({
uid: PropTypes.string.isRequired, uid: PropTypes.string.isRequired,
settings: PropTypes.object.isRequired, settings: PropTypes.shape({
bulkable: PropTypes.bool,
defaultSortBy: PropTypes.string,
defaultSortOrder: PropTypes.string,
filterable: PropTypes.bool,
pageSize: PropTypes.number,
searchable: PropTypes.bool,
}).isRequired,
metadatas: PropTypes.object.isRequired, metadatas: PropTypes.object.isRequired,
options: PropTypes.object.isRequired, options: PropTypes.object.isRequired,
attributes: PropTypes.object.isRequired, attributes: PropTypes.objectOf(
PropTypes.shape({
type: PropTypes.string,
})
).isRequired,
}).isRequired, }).isRequired,
slug: PropTypes.string.isRequired, slug: PropTypes.string.isRequired,
updateLayout: PropTypes.func.isRequired,
}; };
export default memo(ListSettingsView); export default memo(ListSettingsView);

View File

@ -78,10 +78,6 @@ const reducer = (state = initialState, action) =>
// set(draftState, [...fieldMetadataPath, 'sortable'], state.labelForm.sortable); // set(draftState, [...fieldMetadataPath, 'sortable'], state.labelForm.sortable);
// break; // break;
// } // }
case 'SUBMIT_SUCCEEDED': {
draftState.initialData = state.modifiedData;
break;
}
default: default:
return draftState; return draftState;
} }

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { render, waitFor, screen } from '@testing-library/react'; import { render, waitFor, screen, fireEvent } from '@testing-library/react';
import { Router } from 'react-router-dom'; import { Router } from 'react-router-dom';
import { createMemoryHistory } from 'history'; import { createMemoryHistory } from 'history';
import { IntlProvider } from 'react-intl'; import { IntlProvider } from 'react-intl';
@ -49,10 +49,7 @@ const layout = {
options: {}, options: {},
}; };
const history = createMemoryHistory(); const makeApp = history => (
history.push('/content-manager');
const App = (
<Router history={history}> <Router history={history}>
<ModelsContext.Provider value={{ refetchData: jest.fn() }}> <ModelsContext.Provider value={{ refetchData: jest.fn() }}>
<QueryClientProvider client={client}> <QueryClientProvider client={client}>
@ -72,7 +69,10 @@ const App = (
describe('ADMIN | CM | LV | Configure the view', () => { describe('ADMIN | CM | LV | Configure the view', () => {
it('renders and matches the snapshot', async () => { it('renders and matches the snapshot', async () => {
const { container } = render(App); const history = createMemoryHistory();
history.push('/content-manager');
const { container } = render(makeApp(history));
await waitFor(() => { await waitFor(() => {
expect(screen.getByText('Configure the view - Michka')).toBeInTheDocument(); expect(screen.getByText('Configure the view - Michka')).toBeInTheDocument();
}); });
@ -797,6 +797,7 @@ describe('ADMIN | CM | LV | Configure the view', () => {
<a <a
class="c6" class="c6"
href="/content-manager/undefined/api::restaurant.restaurant?page=1&sort=undefined:undefined" href="/content-manager/undefined/api::restaurant.restaurant?page=1&sort=undefined:undefined"
id="go-back"
> >
<span <span
aria-hidden="true" aria-hidden="true"
@ -1323,4 +1324,22 @@ describe('ADMIN | CM | LV | Configure the view', () => {
</div> </div>
`); `);
}); });
it('should keep plugins query params when arriving on the page and going back', async () => {
const history = createMemoryHistory();
history.push(
'/content-manager/collectionType/api::category.category/configurations/list?plugins[i18n][locale]=fr'
);
const { container } = render(makeApp(history));
await waitFor(() => {
expect(screen.getByText('Configure the view - Michka')).toBeInTheDocument();
});
expect(history.location.search).toEqual('?plugins[i18n][locale]=fr');
fireEvent.click(container.querySelector('#go-back'));
expect(history.location.search).toEqual(
'?page=1&sort=undefined:undefined&plugins[i18n][locale]=fr'
);
});
}); });

View File

@ -0,0 +1,8 @@
export const EXCLUDED_SORT_OPTIONS = [
'media',
'richtext',
'dynamiczone',
'relation',
'component',
'json',
];

View File

@ -81,6 +81,7 @@ function ListView({
const [{ query }] = useQueryParams(); const [{ query }] = useQueryParams();
const params = buildQueryString(query); const params = buildQueryString(query);
const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
const { pathname } = useLocation(); const { pathname } = useLocation();
const { push } = useHistory(); const { push } = useHistory();
@ -136,8 +137,6 @@ function ListView({
return; return;
} }
console.log('iii');
console.error(err); console.error(err);
toggleNotification({ toggleNotification({
type: 'warning', type: 'warning',
@ -256,7 +255,7 @@ function ListView({
trackUsageRef.current('willCreateEntry', trackerProperty); trackUsageRef.current('willCreateEntry', trackerProperty);
push({ push({
pathname: `${pathname}/create`, pathname: `${pathname}/create`,
search: query.plugins ? stringify({ plugins: query.plugins }, { encode: false }) : '', search: query.plugins ? pluginsQueryParams : '',
}); });
}} }}
startIcon={<Add />} startIcon={<Add />}
@ -282,7 +281,8 @@ function ListView({
<FieldPicker layout={layout} /> <FieldPicker layout={layout} />
<CheckPermissions permissions={cmPermissions.collectionTypesConfigurations}> <CheckPermissions permissions={cmPermissions.collectionTypesConfigurations}>
<IconButtonCustom <IconButtonCustom
onClick={() => push(`${slug}/configurations/list`)} onClick={() =>
push({ pathname: `${slug}/configurations/list`, search: pluginsQueryParams })}
icon={<Settings />} icon={<Settings />}
label={formatMessage({ label={formatMessage({
id: 'app.links.configure-view', id: 'app.links.configure-view',