diff --git a/packages/core/admin/admin/src/content-manager/pages/ListSettingsView/components/DraggableCard.js b/packages/core/admin/admin/src/content-manager/pages/ListSettingsView/components/DraggableCard.js
new file mode 100644
index 0000000000..c985095fd8
--- /dev/null
+++ b/packages/core/admin/admin/src/content-manager/pages/ListSettingsView/components/DraggableCard.js
@@ -0,0 +1,126 @@
+import React, { useRef } from 'react';
+import styled from 'styled-components';
+import PropTypes from 'prop-types';
+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';
+
+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)`
+ min-width: ${200 / 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 editButtonRef = useRef();
+
+ const rowHandleClick = () => {
+ if (editButtonRef.current) {
+ editButtonRef.current.click();
+ }
+ };
+
+ return (
+
+
+
+
+
+
+ {title}
+
+
+ {
+ e.stopPropagation();
+ console.log('edit');
+ }}
+ aria-label={`edit ${title}`}
+ type="button"
+ >
+
+
+
+
+
+
+
+
+ );
+};
+
+DraggableCard.defaultProps = {
+ onRemoveField: () => {},
+};
+
+DraggableCard.propTypes = {
+ onRemoveField: PropTypes.func,
+ title: PropTypes.string.isRequired,
+};
+
+export default DraggableCard;
diff --git a/packages/core/admin/admin/src/content-manager/pages/ListSettingsView/index.js b/packages/core/admin/admin/src/content-manager/pages/ListSettingsView/index.js
index 0806bcd420..b7798467be 100644
--- a/packages/core/admin/admin/src/content-manager/pages/ListSettingsView/index.js
+++ b/packages/core/admin/admin/src/content-manager/pages/ListSettingsView/index.js
@@ -1,52 +1,68 @@
-import React, {
- memo,
- useContext,
- // useMemo,
- useReducer,
- useState,
-} from 'react';
+import React, { memo, useContext, useMemo, useReducer, useState } from 'react';
import PropTypes from 'prop-types';
+import styled from 'styled-components';
import { useMutation } from 'react-query';
-import { isEqual, upperFirst, pick } from 'lodash';
+import { isEqual, upperFirst, pick, get } from 'lodash';
import { stringify } from 'qs';
import { useNotification, useTracking, ConfirmDialog } from '@strapi/helper-plugin';
import { useIntl } from 'react-intl';
import { Box } from '@strapi/parts/Box';
+import { Row } from '@strapi/parts/Row';
+import { Stack } from '@strapi/parts/Stack';
import { Divider } from '@strapi/parts/Divider';
import { Layout, HeaderLayout, ContentLayout } from '@strapi/parts/Layout';
import { Link } from '@strapi/parts/Link';
import { Main } from '@strapi/parts/Main';
+import { H3 } from '@strapi/parts/Text';
+import { Select, Option } from '@strapi/parts/Select';
import { Button } from '@strapi/parts/Button';
import CheckIcon from '@strapi/icons/CheckIcon';
import BackIcon from '@strapi/icons/BackIcon';
+// import LayoutDndProvider from '../../components/LayoutDndProvider';
+import { checkIfAttributeIsDisplayable, getTrad } from '../../utils';
import ModelsContext from '../../contexts/ModelsContext';
import { usePluginsQueryParams } from '../../hooks';
import putCMSettingsLV from './utils/api';
import Settings from './components/Settings';
-// import LayoutDndProvider from '../../components/LayoutDndProvider';
+import DraggableCard from './components/DraggableCard';
import init from './init';
import reducer, { initialState } from './reducer';
+const Flex = styled(Box)`
+ flex: ${({ size }) => size};
+`;
+
+const ScrollableContainer = styled(Flex)`
+ overflow-x: scroll;
+ overflow-y: hidden;
+`;
+
+const SelectContainer = styled(Flex)`
+ max-width: ${200 / 16}rem;
+`;
+
const ListSettingsView = ({ layout, slug, updateLayout }) => {
+ const { formatMessage } = useIntl();
+ const { trackUsage } = useTracking();
const pluginsQueryParams = usePluginsQueryParams();
const toggleNotification = useNotification();
const { refetchData } = useContext(ModelsContext);
+ const [showWarningSubmit, setWarningSubmit] = useState(false);
+ const toggleWarningSubmit = () => setWarningSubmit(prevState => !prevState);
const [reducerState, dispatch] = useReducer(reducer, initialState, () =>
init(initialState, layout)
);
// const [isOpen, setIsOpen] = useState(false);
// const [isModalFormOpen, setIsModalFormOpen] = useState(false);
// const [isDraggingSibling, setIsDraggingSibling] = useState(false);
- const { formatMessage } = useIntl();
- const { trackUsage } = useTracking();
// const toggleModalForm = () => setIsModalFormOpen(prevState => !prevState);
+
const {
// labelForm,
// labelToEdit,
initialData,
modifiedData,
} = reducerState;
- // const metadatas = get(modifiedData, ['metadatas'], {});
// const attributes = useMemo(() => {
// return get(modifiedData, ['attributes'], {});
@@ -54,66 +70,12 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
const { attributes } = layout;
- // const displayedFields = useMemo(() => {
- // return get(modifiedData, ['layouts', 'list'], []);
- // }, [modifiedData]);
+ const displayedFields = useMemo(() => {
+ return get(modifiedData, ['layouts', 'list'], []);
+ }, [modifiedData]);
const excludedSortOptions = ['media', 'richtext', 'dynamiczone', 'relation', 'component', 'json'];
- const sortOptions = Object.entries(attributes).reduce((acc, cur) => {
- const [name, { type }] = cur;
-
- if (!excludedSortOptions.includes(type)) {
- acc.push(name);
- }
-
- 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 => {
- // 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 [showWarningSubmit, setWarningSubmit] = useState(false);
- const toggleWarningSubmit = () => setWarningSubmit(prevState => !prevState);
-
- const handleSubmit = e => {
- e.preventDefault();
- toggleWarningSubmit();
- trackUsage('willSaveContentTypeLayout');
- };
-
const goBackUrl = () => {
const {
settings: { pageSize, defaultSortBy, defaultSortOrder },
@@ -133,19 +95,59 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
return `/content-manager/${kind}/${uid}?${goBackSearch}`;
};
- // const handleChangeEditLabel = ({ target: { name, value } }) => {
- // dispatch({
- // type: 'ON_CHANGE_LABEL_METAS',
- // name,
- // value,
- // });
- // };
+ 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 body = pick(modifiedData, ['layouts', 'settings', 'metadatas']);
submitMutation.mutateAsync(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 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), {
onSuccess: async ({ data: { data } }) => {
updateLayout(data);
@@ -164,9 +166,42 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
},
refetchActive: true,
});
-
const { isLoading: isSubmittingForm } = submitMutation;
+ const metadatas = get(modifiedData, ['metadatas'], {});
+ const listRemainingFields = useMemo(() => {
+ return Object.keys(metadatas)
+ .filter(key => {
+ return checkIfAttributeIsDisplayable(get(attributes, key, {}));
+ })
+ .filter(field => {
+ return !displayedFields.includes(field);
+ })
+ .sort();
+ }, [displayedFields, attributes, metadatas]);
+
+ // 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) => {
// dispatch({
// type: 'MOVE_FIELD',
@@ -263,9 +298,47 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
onChange={handleChange}
sortOptions={sortOptions}
/>
-
+
+
+
+ {formatMessage({
+ id: 'content-manager.containers.SettingPage.view',
+ defaultMessage: 'View',
+ })}
+
+
+
+
+
+ {displayedFields.map((field, index) => (
+ handleRemoveField(e, index)}
+ key={field}
+ title={field}
+ />
+ ))}
+
+
+
+
+
+
// eslint-disable-next-line consistent-return
produce(state, draftState => {
- // const layoutFieldListPath = ['modifiedData', 'layouts', 'list'];
+ const layoutFieldListPath = ['modifiedData', 'layouts', 'list'];
switch (action.type) {
- // case 'ADD_FIELD': {
- // const layoutFieldList = get(state, layoutFieldListPath, []);
- // set(draftState, layoutFieldListPath, [...layoutFieldList, action.item]);
- // break;
- // }
+ case 'ADD_FIELD': {
+ const layoutFieldList = get(state, layoutFieldListPath, []);
+ set(draftState, layoutFieldListPath, [action.item, ...layoutFieldList]);
+ break;
+ }
// case 'MOVE_FIELD': {
// const layoutFieldList = get(state, layoutFieldListPath, []);
// const { originalIndex, atIndex } = action;
@@ -43,15 +43,15 @@ const reducer = (state = initialState, action) =>
// draftState.modifiedData = state.initialData;
// break;
// }
- // case 'REMOVE_FIELD': {
- // const layoutFieldList = get(state, layoutFieldListPath, []);
- // set(
- // draftState,
- // layoutFieldListPath,
- // layoutFieldList.filter((_, index) => action.index !== index)
- // );
- // break;
- // }
+ case 'REMOVE_FIELD': {
+ const layoutFieldList = get(state, layoutFieldListPath, []);
+ set(
+ draftState,
+ layoutFieldListPath,
+ layoutFieldList.filter((_, index) => action.index !== index)
+ );
+ break;
+ }
// case 'SET_LABEL_TO_EDIT': {
// const { labelToEdit } = action;
// draftState.labelToEdit = labelToEdit;
diff --git a/packages/core/admin/admin/src/content-manager/pages/ListSettingsView/tests/reducer.test.js b/packages/core/admin/admin/src/content-manager/pages/ListSettingsView/tests/reducer.test.js
index 90505406e9..8e3d8a1ae4 100644
--- a/packages/core/admin/admin/src/content-manager/pages/ListSettingsView/tests/reducer.test.js
+++ b/packages/core/admin/admin/src/content-manager/pages/ListSettingsView/tests/reducer.test.js
@@ -19,21 +19,21 @@ describe('CONTENT MANAGER | CONTAINERS | ListSettingsView | reducer', () => {
expect(reducer(state, {})).toEqual(expected);
});
- // describe('ADD_FIELD', () => {
- // it('should add a field to the layout correctly', () => {
- // const expected = {
- // ...state,
- // modifiedData: {
- // layouts: {
- // list: ['title'],
- // },
- // },
- // };
- // const action = { type: 'ADD_FIELD', item: 'title' };
+ describe('ADD_FIELD', () => {
+ it('should add a field to the layout correctly', () => {
+ const expected = {
+ modifiedData: {
+ layouts: {
+ list: ['title'],
+ },
+ },
+ ...state,
+ };
+ const action = { type: 'ADD_FIELD', item: 'title' };
- // expect(reducer(state, action)).toEqual(expected);
- // });
- // });
+ expect(reducer(state, action)).toEqual(expected);
+ });
+ });
// describe('MOVE_FIELD', () => {
// it('should replace the title by the description and vice-versa', () => {
@@ -103,32 +103,32 @@ describe('CONTENT MANAGER | CONTAINERS | ListSettingsView | reducer', () => {
// });
// });
- // describe('REMOVE_FIELD', () => {
- // it('should remove the field', () => {
- // state.modifiedData = {
- // layouts: {
- // list: ['id', 'description', 'title'],
- // },
- // settings: {
- // defaultSortBy: 'id',
- // },
- // };
- // const expected = {
- // ...state,
- // modifiedData: {
- // layouts: {
- // list: ['id', 'title'],
- // },
- // settings: {
- // defaultSortBy: 'id',
- // },
- // },
- // };
- // const action = { type: 'REMOVE_FIELD', index: 1 };
+ describe('REMOVE_FIELD', () => {
+ it('should remove the field', () => {
+ state.modifiedData = {
+ layouts: {
+ list: ['id', 'description', 'title'],
+ },
+ settings: {
+ defaultSortBy: 'id',
+ },
+ };
+ const expected = {
+ ...state,
+ modifiedData: {
+ layouts: {
+ list: ['id', 'title'],
+ },
+ settings: {
+ defaultSortBy: 'id',
+ },
+ },
+ };
+ const action = { type: 'REMOVE_FIELD', index: 1 };
- // expect(reducer(state, action)).toEqual(expected);
- // });
- // });
+ expect(reducer(state, action)).toEqual(expected);
+ });
+ });
// describe('SET_LABEL_TO_EDIT', () => {
// it('should set the label form data of the field to edit', () => {