mirror of
https://github.com/strapi/strapi.git
synced 2025-07-27 02:44:13 +00:00
Migration/ Configure LV add+remove field (#11247)
* add and delete view field * removed submit succeded reducer test * added test * test add field + feedback fixes * replaced select add field by simple menu + updated test * made View its own component * UI badges feedback fix * feedback fixes
This commit is contained in:
parent
44e60f304e
commit
46e01ea7d6
@ -0,0 +1,152 @@
|
|||||||
|
import React, { useRef } from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
|
import { Row } from '@strapi/parts/Row';
|
||||||
|
import { Box } from '@strapi/parts/Box';
|
||||||
|
import { ButtonText } from '@strapi/parts/Text';
|
||||||
|
import { Stack } from '@strapi/parts/Stack';
|
||||||
|
import EditIcon from '@strapi/icons/EditIcon';
|
||||||
|
import CloseAlertIcon from '@strapi/icons/CloseAlertIcon';
|
||||||
|
import Drag from '@strapi/icons/Drag';
|
||||||
|
import { getTrad } from '../../../utils';
|
||||||
|
|
||||||
|
const ActionButton = styled.button`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: ${({ theme }) => theme.spaces[7]};
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding: 0 ${({ theme }) => theme.spaces[3]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const DragButton = styled(ActionButton)`
|
||||||
|
padding: 0 ${({ theme }) => theme.spaces[3]};
|
||||||
|
border-right: 1px solid ${({ theme }) => theme.colors.neutral150};
|
||||||
|
cursor: all-scroll;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: ${12 / 16}rem;
|
||||||
|
height: ${12 / 16}rem;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const FieldContainer = styled(Row)`
|
||||||
|
max-height: ${32 / 16}rem;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: ${10 / 16}rem;
|
||||||
|
height: ${10 / 16}rem;
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: ${({ theme }) => theme.colors.neutral600};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: ${({ theme }) => theme.colors.primary100};
|
||||||
|
border-color: ${({ theme }) => theme.colors.primary200};
|
||||||
|
|
||||||
|
svg {
|
||||||
|
path {
|
||||||
|
fill: ${({ theme }) => theme.colors.primary600};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
${ButtonText} {
|
||||||
|
color: ${({ theme }) => theme.colors.primary600};
|
||||||
|
}
|
||||||
|
|
||||||
|
${DragButton} {
|
||||||
|
border-right: 1px solid ${({ theme }) => theme.colors.primary200};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const FieldWrapper = styled(Box)`
|
||||||
|
&:last-child {
|
||||||
|
padding-right: ${({ theme }) => theme.spaces[3]};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const DraggableCard = ({ title, onRemoveField }) => {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
const editButtonRef = useRef();
|
||||||
|
const cardTitle = title.length > 20 ? `${title.substring(0, 20)}...` : title;
|
||||||
|
|
||||||
|
const handleClickEditRow = () => {
|
||||||
|
if (editButtonRef.current) {
|
||||||
|
editButtonRef.current.click();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FieldWrapper>
|
||||||
|
<FieldContainer
|
||||||
|
borderColor="neutral150"
|
||||||
|
background="neutral100"
|
||||||
|
hasRadius
|
||||||
|
justifyContent="space-between"
|
||||||
|
onClick={handleClickEditRow}
|
||||||
|
>
|
||||||
|
<Stack horizontal size={3}>
|
||||||
|
<DragButton
|
||||||
|
aria-label={formatMessage(
|
||||||
|
{
|
||||||
|
id: getTrad('components.DraggableCard.move.field'),
|
||||||
|
defaultMessage: 'Move {item}',
|
||||||
|
},
|
||||||
|
{ item: title }
|
||||||
|
)}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<Drag />
|
||||||
|
</DragButton>
|
||||||
|
<ButtonText>{cardTitle}</ButtonText>
|
||||||
|
</Stack>
|
||||||
|
<Row paddingLeft={3}>
|
||||||
|
<ActionButton
|
||||||
|
ref={editButtonRef}
|
||||||
|
onClick={e => {
|
||||||
|
e.stopPropagation();
|
||||||
|
console.log('edit');
|
||||||
|
}}
|
||||||
|
aria-label={formatMessage(
|
||||||
|
{
|
||||||
|
id: getTrad('components.DraggableCard.edit.field'),
|
||||||
|
defaultMessage: 'Edit {item}',
|
||||||
|
},
|
||||||
|
{ item: title }
|
||||||
|
)}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<EditIcon />
|
||||||
|
</ActionButton>
|
||||||
|
<ActionButton
|
||||||
|
onClick={onRemoveField}
|
||||||
|
data-testid={`delete-${title}`}
|
||||||
|
aria-label={formatMessage(
|
||||||
|
{
|
||||||
|
id: getTrad('components.DraggableCard.delete.field'),
|
||||||
|
defaultMessage: 'Delete {item}',
|
||||||
|
},
|
||||||
|
{ item: title }
|
||||||
|
)}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<CloseAlertIcon />
|
||||||
|
</ActionButton>
|
||||||
|
</Row>
|
||||||
|
</FieldContainer>
|
||||||
|
</FieldWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
DraggableCard.propTypes = {
|
||||||
|
onRemoveField: PropTypes.func.isRequired,
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DraggableCard;
|
@ -0,0 +1,91 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { PropTypes } from 'prop-types';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
|
import { Box } from '@strapi/parts/Box';
|
||||||
|
import { Row } from '@strapi/parts/Row';
|
||||||
|
import { Stack } from '@strapi/parts/Stack';
|
||||||
|
import { H3 } from '@strapi/parts/Text';
|
||||||
|
import { SimpleMenu, MenuItem } from '@strapi/parts/SimpleMenu';
|
||||||
|
import { IconButton } from '@strapi/parts/IconButton';
|
||||||
|
import AddIcon from '@strapi/icons/AddIcon';
|
||||||
|
import DraggableCard from './DraggableCard';
|
||||||
|
import { getTrad } from '../../../utils';
|
||||||
|
|
||||||
|
const Flex = styled(Box)`
|
||||||
|
flex: ${({ size }) => size};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ScrollableContainer = styled(Flex)`
|
||||||
|
overflow-x: scroll;
|
||||||
|
overflow-y: hidden;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const SelectContainer = styled(Flex)`
|
||||||
|
max-width: ${32 / 16}rem;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const View = ({ listRemainingFields, displayedFields, handleAddField, handleRemoveField }) => {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Box paddingBottom={4}>
|
||||||
|
<H3 as="h2">
|
||||||
|
{formatMessage({
|
||||||
|
id: getTrad('containers.SettingPage.view'),
|
||||||
|
defaultMessage: 'View',
|
||||||
|
})}
|
||||||
|
</H3>
|
||||||
|
</Box>
|
||||||
|
<Row
|
||||||
|
paddingTop={4}
|
||||||
|
paddingLeft={4}
|
||||||
|
paddingRight={4}
|
||||||
|
borderColor="neutral300"
|
||||||
|
borderStyle="dashed"
|
||||||
|
borderWidth="1px"
|
||||||
|
hasRadius
|
||||||
|
>
|
||||||
|
<ScrollableContainer size="1" paddingBottom={4}>
|
||||||
|
<Stack horizontal size={3}>
|
||||||
|
{displayedFields.map((field, index) => (
|
||||||
|
<DraggableCard
|
||||||
|
onRemoveField={e => handleRemoveField(e, index)}
|
||||||
|
key={field}
|
||||||
|
title={field}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
</ScrollableContainer>
|
||||||
|
<SelectContainer size="auto" paddingBottom={4}>
|
||||||
|
<SimpleMenu
|
||||||
|
label={formatMessage({
|
||||||
|
id: getTrad('components.FieldSelect.label'),
|
||||||
|
defaultMessage: 'Add a field',
|
||||||
|
})}
|
||||||
|
as={IconButton}
|
||||||
|
icon={<AddIcon />}
|
||||||
|
disabled={listRemainingFields.length <= 0}
|
||||||
|
data-testid="add-field"
|
||||||
|
>
|
||||||
|
{listRemainingFields.map(field => (
|
||||||
|
<MenuItem key={field} onClick={() => handleAddField(field)}>
|
||||||
|
{field}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</SimpleMenu>
|
||||||
|
</SelectContainer>
|
||||||
|
</Row>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
View.propTypes = {
|
||||||
|
displayedFields: PropTypes.array.isRequired,
|
||||||
|
handleAddField: PropTypes.func.isRequired,
|
||||||
|
handleRemoveField: PropTypes.func.isRequired,
|
||||||
|
listRemainingFields: PropTypes.array.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default View;
|
@ -1,10 +1,4 @@
|
|||||||
import React, {
|
import React, { memo, useContext, useReducer, useState } from 'react';
|
||||||
memo,
|
|
||||||
useContext,
|
|
||||||
// useMemo,
|
|
||||||
useReducer,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useMutation } from 'react-query';
|
import { useMutation } from 'react-query';
|
||||||
import isEqual from 'lodash/isEqual';
|
import isEqual from 'lodash/isEqual';
|
||||||
@ -21,35 +15,39 @@ import { Main } from '@strapi/parts/Main';
|
|||||||
import { Button } from '@strapi/parts/Button';
|
import { Button } from '@strapi/parts/Button';
|
||||||
import CheckIcon from '@strapi/icons/CheckIcon';
|
import CheckIcon from '@strapi/icons/CheckIcon';
|
||||||
import BackIcon from '@strapi/icons/BackIcon';
|
import BackIcon from '@strapi/icons/BackIcon';
|
||||||
|
// import LayoutDndProvider from '../../components/LayoutDndProvider';
|
||||||
|
import { checkIfAttributeIsDisplayable, getTrad } from '../../utils';
|
||||||
import ModelsContext from '../../contexts/ModelsContext';
|
import ModelsContext from '../../contexts/ModelsContext';
|
||||||
import { usePluginsQueryParams } from '../../hooks';
|
import { usePluginsQueryParams } from '../../hooks';
|
||||||
import putCMSettingsLV from './utils/api';
|
import putCMSettingsLV from './utils/api';
|
||||||
import Settings from './components/Settings';
|
import Settings from './components/Settings';
|
||||||
// import LayoutDndProvider from '../../components/LayoutDndProvider';
|
import View from './components/View';
|
||||||
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';
|
import { EXCLUDED_SORT_OPTIONS } from './utils/excludedSortOptions';
|
||||||
|
|
||||||
const ListSettingsView = ({ layout, slug }) => {
|
const ListSettingsView = ({ layout, slug }) => {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
const { trackUsage } = useTracking();
|
||||||
const pluginsQueryParams = usePluginsQueryParams();
|
const pluginsQueryParams = usePluginsQueryParams();
|
||||||
const toggleNotification = useNotification();
|
const toggleNotification = useNotification();
|
||||||
const { refetchData } = useContext(ModelsContext);
|
const { refetchData } = useContext(ModelsContext);
|
||||||
|
const [showWarningSubmit, setWarningSubmit] = useState(false);
|
||||||
|
const toggleWarningSubmit = () => setWarningSubmit(prevState => !prevState);
|
||||||
const [reducerState, dispatch] = useReducer(reducer, initialState, () =>
|
const [reducerState, dispatch] = useReducer(reducer, initialState, () =>
|
||||||
init(initialState, layout)
|
init(initialState, layout)
|
||||||
);
|
);
|
||||||
// const [isOpen, setIsOpen] = useState(false);
|
// const [isOpen, setIsOpen] = useState(false);
|
||||||
// const [isModalFormOpen, setIsModalFormOpen] = useState(false);
|
// const [isModalFormOpen, setIsModalFormOpen] = useState(false);
|
||||||
// const [isDraggingSibling, setIsDraggingSibling] = useState(false);
|
// const [isDraggingSibling, setIsDraggingSibling] = useState(false);
|
||||||
const { formatMessage } = useIntl();
|
|
||||||
const { trackUsage } = useTracking();
|
|
||||||
// const toggleModalForm = () => setIsModalFormOpen(prevState => !prevState);
|
// const toggleModalForm = () => setIsModalFormOpen(prevState => !prevState);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
// labelForm,
|
// labelForm,
|
||||||
// labelToEdit,
|
// labelToEdit,
|
||||||
initialData,
|
initialData,
|
||||||
modifiedData,
|
modifiedData,
|
||||||
} = reducerState;
|
} = reducerState;
|
||||||
// const metadatas = get(modifiedData, ['metadatas'], {});
|
|
||||||
|
|
||||||
// const attributes = useMemo(() => {
|
// const attributes = useMemo(() => {
|
||||||
// return get(modifiedData, ['attributes'], {});
|
// return get(modifiedData, ['attributes'], {});
|
||||||
@ -57,11 +55,7 @@ const ListSettingsView = ({ layout, slug }) => {
|
|||||||
|
|
||||||
const { attributes } = layout;
|
const { attributes } = layout;
|
||||||
|
|
||||||
// const displayedFields = useMemo(() => {
|
const displayedFields = modifiedData.layouts.list;
|
||||||
// return get(modifiedData, ['layouts', 'list'], []);
|
|
||||||
// }, [modifiedData]);
|
|
||||||
|
|
||||||
// const excludedSortOptions = ['media', 'richtext', 'dynamiczone', 'relation', 'component', 'json'];
|
|
||||||
|
|
||||||
const sortOptions = Object.entries(attributes).reduce((acc, cur) => {
|
const sortOptions = Object.entries(attributes).reduce((acc, cur) => {
|
||||||
const [name, { type }] = cur;
|
const [name, { type }] = cur;
|
||||||
@ -73,19 +67,6 @@ const ListSettingsView = ({ layout, slug }) => {
|
|||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// const listRemainingFields = useMemo(() => {
|
|
||||||
// return Object.keys(metadatas)
|
|
||||||
// .filter(key => {
|
|
||||||
// return checkIfAttributeIsDisplayable(get(attributes, key, {}));
|
|
||||||
// })
|
|
||||||
// .filter(field => {
|
|
||||||
// return !displayedFields.includes(field);
|
|
||||||
// })
|
|
||||||
// .sort();
|
|
||||||
// }, [displayedFields, attributes, metadatas]);
|
|
||||||
|
|
||||||
// console.log(displayedFields, listRemainingFields);
|
|
||||||
|
|
||||||
// const handleClickEditLabel = labelToEdit => {
|
// const handleClickEditLabel = labelToEdit => {
|
||||||
// dispatch({
|
// dispatch({
|
||||||
// type: 'SET_LABEL_TO_EDIT',
|
// type: 'SET_LABEL_TO_EDIT',
|
||||||
@ -108,15 +89,6 @@ const ListSettingsView = ({ layout, slug }) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const [showWarningSubmit, setWarningSubmit] = useState(false);
|
|
||||||
const toggleWarningSubmit = () => setWarningSubmit(prevState => !prevState);
|
|
||||||
|
|
||||||
const handleSubmit = e => {
|
|
||||||
e.preventDefault();
|
|
||||||
toggleWarningSubmit();
|
|
||||||
trackUsage('willSaveContentTypeLayout');
|
|
||||||
};
|
|
||||||
|
|
||||||
const goBackUrl = () => {
|
const goBackUrl = () => {
|
||||||
const {
|
const {
|
||||||
settings: { pageSize, defaultSortBy, defaultSortOrder },
|
settings: { pageSize, defaultSortBy, defaultSortOrder },
|
||||||
@ -136,24 +108,42 @@ const ListSettingsView = ({ layout, slug }) => {
|
|||||||
return `/content-manager/${kind}/${uid}?${goBackSearch}`;
|
return `/content-manager/${kind}/${uid}?${goBackSearch}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
// const handleChangeEditLabel = ({ target: { name, value } }) => {
|
|
||||||
// dispatch({
|
|
||||||
// type: 'ON_CHANGE_LABEL_METAS',
|
|
||||||
// name,
|
|
||||||
// value,
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
const body = pick(modifiedData, ['layouts', 'settings', 'metadatas']);
|
const body = pick(modifiedData, ['layouts', 'settings', 'metadatas']);
|
||||||
submitMutation.mutateAsync(body);
|
submitMutation.mutate(body);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddField = item => {
|
||||||
|
dispatch({
|
||||||
|
type: 'ADD_FIELD',
|
||||||
|
item,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemoveField = (e, index) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
if (displayedFields.length === 1) {
|
||||||
|
toggleNotification({
|
||||||
|
type: 'info',
|
||||||
|
message: { id: getTrad('notification.info.minimumFields') },
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
dispatch({
|
||||||
|
type: 'REMOVE_FIELD',
|
||||||
|
index,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
toggleWarningSubmit();
|
||||||
|
trackUsage('willSaveContentTypeLayout');
|
||||||
};
|
};
|
||||||
|
|
||||||
const submitMutation = useMutation(body => putCMSettingsLV(body, slug), {
|
const submitMutation = useMutation(body => putCMSettingsLV(body, slug), {
|
||||||
onSuccess: async () => {
|
onSuccess: () => {
|
||||||
dispatch({
|
|
||||||
type: 'SUBMIT_SUCCEEDED',
|
|
||||||
});
|
|
||||||
trackUsage('didEditListSettings');
|
trackUsage('didEditListSettings');
|
||||||
refetchData();
|
refetchData();
|
||||||
},
|
},
|
||||||
@ -163,11 +153,46 @@ const ListSettingsView = ({ layout, slug }) => {
|
|||||||
message: { id: 'notification.error' },
|
message: { id: 'notification.error' },
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
refetchActive: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { isLoading: isSubmittingForm } = submitMutation;
|
const { isLoading: isSubmittingForm } = submitMutation;
|
||||||
|
|
||||||
|
const listRemainingFields = Object.entries(attributes)
|
||||||
|
.reduce((acc, cur) => {
|
||||||
|
const [attrName, fieldSchema] = cur;
|
||||||
|
|
||||||
|
const isDisplayable = checkIfAttributeIsDisplayable(fieldSchema);
|
||||||
|
const isAlreadyDisplayed = displayedFields.includes(attrName);
|
||||||
|
|
||||||
|
if (isDisplayable && !isAlreadyDisplayed) {
|
||||||
|
acc.push(attrName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, [])
|
||||||
|
.sort();
|
||||||
|
|
||||||
|
// const handleClickEditLabel = labelToEdit => {
|
||||||
|
// dispatch({
|
||||||
|
// type: 'SET_LABEL_TO_EDIT',
|
||||||
|
// labelToEdit,
|
||||||
|
// });
|
||||||
|
// toggleModalForm();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const handleClosed = () => {
|
||||||
|
// dispatch({
|
||||||
|
// type: 'UNSET_LABEL_TO_EDIT',
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const handleChangeEditLabel = ({ target: { name, value } }) => {
|
||||||
|
// dispatch({
|
||||||
|
// type: 'ON_CHANGE_LABEL_METAS',
|
||||||
|
// name,
|
||||||
|
// value,
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
// const move = (originalIndex, atIndex) => {
|
// const move = (originalIndex, atIndex) => {
|
||||||
// dispatch({
|
// dispatch({
|
||||||
// type: 'MOVE_FIELD',
|
// type: 'MOVE_FIELD',
|
||||||
@ -238,12 +263,12 @@ const ListSettingsView = ({ layout, slug }) => {
|
|||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
subtitle={formatMessage({
|
subtitle={formatMessage({
|
||||||
id: `components.SettingsViewWrapper.pluginHeader.description.list-settings`,
|
id: getTrad('components.SettingsViewWrapper.pluginHeader.description.list-settings'),
|
||||||
defaultMessage: `Define the settings of the list view.`,
|
defaultMessage: 'Define the settings of the list view.',
|
||||||
})}
|
})}
|
||||||
title={formatMessage(
|
title={formatMessage(
|
||||||
{
|
{
|
||||||
id: 'components.SettingsViewWrapper.pluginHeader.title',
|
id: getTrad('components.SettingsViewWrapper.pluginHeader.title'),
|
||||||
defaultMessage: 'Configure the view - {name}',
|
defaultMessage: 'Configure the view - {name}',
|
||||||
},
|
},
|
||||||
{ name: upperFirst(modifiedData.info.label) }
|
{ name: upperFirst(modifiedData.info.label) }
|
||||||
@ -264,14 +289,20 @@ const ListSettingsView = ({ layout, slug }) => {
|
|||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
sortOptions={sortOptions}
|
sortOptions={sortOptions}
|
||||||
/>
|
/>
|
||||||
<Box padding={6}>
|
<Box paddingTop={6} paddingBottom={6}>
|
||||||
<Divider />
|
<Divider />
|
||||||
</Box>
|
</Box>
|
||||||
|
<View
|
||||||
|
listRemainingFields={listRemainingFields}
|
||||||
|
displayedFields={displayedFields}
|
||||||
|
handleAddField={handleAddField}
|
||||||
|
handleRemoveField={handleRemoveField}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</ContentLayout>
|
</ContentLayout>
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
bodyText={{
|
bodyText={{
|
||||||
id: 'content-manager.popUpWarning.warning.updateAllSettings',
|
id: getTrad('popUpWarning.warning.updateAllSettings'),
|
||||||
defaultMessage: 'This will modify all your settings',
|
defaultMessage: 'This will modify all your settings',
|
||||||
}}
|
}}
|
||||||
iconRightButton={<CheckIcon />}
|
iconRightButton={<CheckIcon />}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import produce from 'immer'; // current
|
import produce from 'immer'; // current
|
||||||
import set from 'lodash/set';
|
import set from 'lodash/set';
|
||||||
// import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
// import { arrayMoveItem } from '../../utils';
|
// import { arrayMoveItem } from '../../utils';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
@ -14,13 +14,13 @@ const initialState = {
|
|||||||
const reducer = (state = initialState, action) =>
|
const reducer = (state = initialState, action) =>
|
||||||
// eslint-disable-next-line consistent-return
|
// eslint-disable-next-line consistent-return
|
||||||
produce(state, draftState => {
|
produce(state, draftState => {
|
||||||
// const layoutFieldListPath = ['modifiedData', 'layouts', 'list'];
|
const layoutFieldListPath = ['modifiedData', 'layouts', 'list'];
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
// case 'ADD_FIELD': {
|
case 'ADD_FIELD': {
|
||||||
// const layoutFieldList = get(state, layoutFieldListPath, []);
|
const layoutFieldList = get(state, layoutFieldListPath, []);
|
||||||
// set(draftState, layoutFieldListPath, [...layoutFieldList, action.item]);
|
set(draftState, layoutFieldListPath, [action.item, ...layoutFieldList]);
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// case 'MOVE_FIELD': {
|
// case 'MOVE_FIELD': {
|
||||||
// const layoutFieldList = get(state, layoutFieldListPath, []);
|
// const layoutFieldList = get(state, layoutFieldListPath, []);
|
||||||
// const { originalIndex, atIndex } = action;
|
// const { originalIndex, atIndex } = action;
|
||||||
@ -43,15 +43,15 @@ const reducer = (state = initialState, action) =>
|
|||||||
// draftState.modifiedData = state.initialData;
|
// draftState.modifiedData = state.initialData;
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
// case 'REMOVE_FIELD': {
|
case 'REMOVE_FIELD': {
|
||||||
// const layoutFieldList = get(state, layoutFieldListPath, []);
|
const layoutFieldList = get(state, layoutFieldListPath, []);
|
||||||
// set(
|
set(
|
||||||
// draftState,
|
draftState,
|
||||||
// layoutFieldListPath,
|
layoutFieldListPath,
|
||||||
// layoutFieldList.filter((_, index) => action.index !== index)
|
layoutFieldList.filter((_, index) => action.index !== index)
|
||||||
// );
|
);
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// case 'SET_LABEL_TO_EDIT': {
|
// case 'SET_LABEL_TO_EDIT': {
|
||||||
// const { labelToEdit } = action;
|
// const { labelToEdit } = action;
|
||||||
// draftState.labelToEdit = labelToEdit;
|
// draftState.labelToEdit = labelToEdit;
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -19,21 +19,21 @@ describe('CONTENT MANAGER | CONTAINERS | ListSettingsView | reducer', () => {
|
|||||||
expect(reducer(state, {})).toEqual(expected);
|
expect(reducer(state, {})).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
// describe('ADD_FIELD', () => {
|
describe('ADD_FIELD', () => {
|
||||||
// it('should add a field to the layout correctly', () => {
|
it('should add a field to the layout correctly', () => {
|
||||||
// const expected = {
|
const expected = {
|
||||||
// ...state,
|
...state,
|
||||||
// modifiedData: {
|
modifiedData: {
|
||||||
// layouts: {
|
layouts: {
|
||||||
// list: ['title'],
|
list: ['title'],
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// };
|
};
|
||||||
// const action = { type: 'ADD_FIELD', item: 'title' };
|
const action = { type: 'ADD_FIELD', item: 'title' };
|
||||||
|
|
||||||
// expect(reducer(state, action)).toEqual(expected);
|
expect(reducer(state, action)).toEqual(expected);
|
||||||
// });
|
});
|
||||||
// });
|
});
|
||||||
|
|
||||||
// describe('MOVE_FIELD', () => {
|
// describe('MOVE_FIELD', () => {
|
||||||
// it('should replace the title by the description and vice-versa', () => {
|
// it('should replace the title by the description and vice-versa', () => {
|
||||||
@ -103,32 +103,32 @@ describe('CONTENT MANAGER | CONTAINERS | ListSettingsView | reducer', () => {
|
|||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// describe('REMOVE_FIELD', () => {
|
describe('REMOVE_FIELD', () => {
|
||||||
// it('should remove the field', () => {
|
it('should remove the field', () => {
|
||||||
// state.modifiedData = {
|
state.modifiedData = {
|
||||||
// layouts: {
|
layouts: {
|
||||||
// list: ['id', 'description', 'title'],
|
list: ['id', 'description', 'title'],
|
||||||
// },
|
},
|
||||||
// settings: {
|
settings: {
|
||||||
// defaultSortBy: 'id',
|
defaultSortBy: 'id',
|
||||||
// },
|
},
|
||||||
// };
|
};
|
||||||
// const expected = {
|
const expected = {
|
||||||
// ...state,
|
...state,
|
||||||
// modifiedData: {
|
modifiedData: {
|
||||||
// layouts: {
|
layouts: {
|
||||||
// list: ['id', 'title'],
|
list: ['id', 'title'],
|
||||||
// },
|
},
|
||||||
// settings: {
|
settings: {
|
||||||
// defaultSortBy: 'id',
|
defaultSortBy: 'id',
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// };
|
};
|
||||||
// const action = { type: 'REMOVE_FIELD', index: 1 };
|
const action = { type: 'REMOVE_FIELD', index: 1 };
|
||||||
|
|
||||||
// expect(reducer(state, action)).toEqual(expected);
|
expect(reducer(state, action)).toEqual(expected);
|
||||||
// });
|
});
|
||||||
// });
|
});
|
||||||
|
|
||||||
// describe('SET_LABEL_TO_EDIT', () => {
|
// describe('SET_LABEL_TO_EDIT', () => {
|
||||||
// it('should set the label form data of the field to edit', () => {
|
// it('should set the label form data of the field to edit', () => {
|
||||||
@ -250,45 +250,4 @@ describe('CONTENT MANAGER | CONTAINERS | ListSettingsView | reducer', () => {
|
|||||||
// expect(reducer(state, action)).toEqual(expected);
|
// expect(reducer(state, action)).toEqual(expected);
|
||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
|
|
||||||
describe('SUBMIT_SUCCEEDED', () => {
|
|
||||||
it('should submit the label and the sortable value of the field to edit', () => {
|
|
||||||
state.modifiedData = {
|
|
||||||
metadatas: {
|
|
||||||
cover: {
|
|
||||||
list: {
|
|
||||||
label: 'Cover',
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const expected = {
|
|
||||||
...state,
|
|
||||||
initialData: {
|
|
||||||
metadatas: {
|
|
||||||
cover: {
|
|
||||||
list: {
|
|
||||||
label: 'Cover',
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
modifiedData: {
|
|
||||||
metadatas: {
|
|
||||||
cover: {
|
|
||||||
list: {
|
|
||||||
label: 'Cover',
|
|
||||||
sortable: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const action = { type: 'SUBMIT_SUCCEEDED' };
|
|
||||||
|
|
||||||
expect(reducer(state, action)).toEqual(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -432,6 +432,9 @@
|
|||||||
"content-manager.api.id": "API ID",
|
"content-manager.api.id": "API ID",
|
||||||
"content-manager.components.AddFilterCTA.add": "Filters",
|
"content-manager.components.AddFilterCTA.add": "Filters",
|
||||||
"content-manager.components.AddFilterCTA.hide": "Filters",
|
"content-manager.components.AddFilterCTA.hide": "Filters",
|
||||||
|
"content-manager.components.DraggableCard.edit.field": "Edit {item}",
|
||||||
|
"content-manager.components.DraggableCard.delete.field": "Delete {item}",
|
||||||
|
"content-manager.components.DraggableCard.move.field": "Move {item}",
|
||||||
"content-manager.components.DragHandle-label": "Drag",
|
"content-manager.components.DragHandle-label": "Drag",
|
||||||
"content-manager.components.DraggableAttr.edit": "Click to edit",
|
"content-manager.components.DraggableAttr.edit": "Click to edit",
|
||||||
"content-manager.components.DynamicTable.row-line": "item line {number}",
|
"content-manager.components.DynamicTable.row-line": "item line {number}",
|
||||||
@ -445,6 +448,7 @@
|
|||||||
"content-manager.components.DynamicZone.required": "Component is required",
|
"content-manager.components.DynamicZone.required": "Component is required",
|
||||||
"content-manager.components.EmptyAttributesBlock.button": "Go to settings page",
|
"content-manager.components.EmptyAttributesBlock.button": "Go to settings page",
|
||||||
"content-manager.components.EmptyAttributesBlock.description": "You can change your settings",
|
"content-manager.components.EmptyAttributesBlock.description": "You can change your settings",
|
||||||
|
"content-manager.components.FieldSelect.label": "Add a field",
|
||||||
"content-manager.components.FieldItem.linkToComponentLayout": "Set the component's layout",
|
"content-manager.components.FieldItem.linkToComponentLayout": "Set the component's layout",
|
||||||
"content-manager.components.FilterOptions.button.apply": "Apply",
|
"content-manager.components.FilterOptions.button.apply": "Apply",
|
||||||
"content-manager.components.FiltersPickWrapper.PluginHeader.actions.apply": "Apply",
|
"content-manager.components.FiltersPickWrapper.PluginHeader.actions.apply": "Apply",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user