text: import React, { memo, useContext, useReducer, useState } from 'react';
  import PropTypes from 'prop-types';
  import { useMutation } from 'react-query';
  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 { useNotification, useTracking, ConfirmDialog, Link } from '@strapi/helper-plugin';
  import { useIntl } from 'react-intl';
  import { Box } from '@strapi/design-system/Box';
  import { Divider } from '@strapi/design-system/Divider';
  import { Layout, HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
  import { Main } from '@strapi/design-system/Main';
  import { Button } from '@strapi/design-system/Button';
  import Check from '@strapi/icons/Check';
  import ArrowLeft from '@strapi/icons/ArrowLeft';
  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 SortDisplayedFields from './components/SortDisplayedFields';
  import EditFieldForm from './components/EditFieldForm';
  import init from './init';
  import reducer, { initialState } from './reducer';
  import { EXCLUDED_SORT_OPTIONS } from './utils/excludedSortOptions';
  
  const ListSettingsView = ({ layout, slug }) => {
    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 [isModalFormOpen, setIsModalFormOpen] = useState(false);
    const toggleModalForm = () => setIsModalFormOpen(prevState => !prevState);
    const [reducerState, dispatch] = useReducer(reducer, initialState, () =>
      init(initialState, layout)
    );
    const { fieldToEdit, fieldForm, initialData, modifiedData } = reducerState;
    const { attributes } = layout;
    const displayedFields = modifiedData.layouts.list;
  
    const goBackUrl = () => {
      const {
        settings: { pageSize, defaultSortBy, defaultSortOrder },
        kind,
        uid,
      } = initialData;
      const sort = `${defaultSortBy}:${defaultSortOrder}`;
      const goBackSearch = `${stringify(
        {
          page: 1,
          pageSize,
          sort,
        },
        { encode: false }
      )}${pluginsQueryParams ? `&${pluginsQueryParams}` : ''}`;
  
      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,
      });
    };
  
    const handleConfirm = async () => {
      const body = pick(modifiedData, ['layouts', 'settings', 'metadatas']);
      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 handleClickEditField = fieldToEdit => {
      dispatch({
        type: 'SET_FIELD_TO_EDIT',
        fieldToEdit,
      });
      toggleModalForm();
    };
  
    const handleCloseModal = () => {
      dispatch({
        type: 'UNSET_FIELD_TO_EDIT',
      });
      toggleModalForm();
    };
  
    const handleSubmitFieldEdit = e => {
      e.preventDefault();
      toggleModalForm();
      dispatch({
        type: 'SUBMIT_FIELD_FORM',
      });
    };
  
    const submitMutation = useMutation(body => putCMSettingsLV(body, slug), {
      onSuccess: () => {
        trackUsage('didEditListSettings');
        refetchData();
      },
      onError: () => {
        toggleNotification({
          type: 'warning',
          message: { id: 'notification.error' },
        });
      },
    });
    const { isLoading: isSubmittingForm } = submitMutation;
  
    const handleChangeEditLabel = ({ target: { name, value } }) => {
      dispatch({
        type: 'ON_CHANGE_FIELD_METAS',
        name,
        value,
      });
    };
  
    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 sortOptions = Object.entries(attributes).reduce((acc, cur) => {
      const [name, { type }] = cur;
  
      if (!EXCLUDED_SORT_OPTIONS.includes(type)) {
        acc.push(name);
      }
  
      return acc;
    }, []);
  
    const move = (originalIndex, atIndex) => {
      dispatch({
        type: 'MOVE_FIELD',
        originalIndex,
        atIndex,
      });
    };
  
    return (
      <Layout>
        <Main aria-busy={isSubmittingForm}>
          <form onSubmit={handleSubmit}>
            <HeaderLayout
              navigationAction={
                <Link startIcon={<ArrowLeft />} to={goBackUrl} id="go-back">
                  {formatMessage({ id: 'global.back', defaultMessage: 'Back' })}
                </Link>
              }
              primaryAction={
                <Button
                  size="L"
                  startIcon={<Check />}
                  disabled={isEqual(modifiedData, initialData)}
                  type="submit"
                >
                  {formatMessage({ id: 'global.save', defaultMessage: 'Save' })}
                </Button>
              }
              subtitle={formatMessage({
                id: getTrad('components.SettingsViewWrapper.pluginHeader.description.list-settings'),
                defaultMessage: 'Define the settings of the list view.',
              })}
              title={formatMessage(
                {
                  id: getTrad('components.SettingsViewWrapper.pluginHeader.title'),
                  defaultMessage: 'Configure the view - {name}',
                },
                { name: upperFirst(modifiedData.info.displayName) }
              )}
            />
            <ContentLayout>
              <Box
                background="neutral0"
                hasRadius
                shadow="tableShadow"
                paddingTop={6}
                paddingBottom={6}
                paddingLeft={7}
                paddingRight={7}
              >
                <Settings
                  modifiedData={modifiedData}
                  onChange={handleChange}
                  sortOptions={sortOptions}
                />
                <Box paddingTop={6} paddingBottom={6}>
                  <Divider />
                </Box>
                <SortDisplayedFields
                  listRemainingFields={listRemainingFields}
                  displayedFields={displayedFields}
                  onAddField={handleAddField}
                  onClickEditField={handleClickEditField}
                  onMoveField={move}
                  onRemoveField={handleRemoveField}
                  metadatas={modifiedData.metadatas}
                />
              </Box>
            </ContentLayout>
            <ConfirmDialog
              bodyText={{
                id: getTrad('popUpWarning.warning.updateAllSettings'),
                defaultMessage: 'This will modify all your settings',
              }}
              iconRightButton={<Check />}
              isConfirmButtonLoading={isSubmittingForm}
              isOpen={showWarningSubmit}
              onToggleDialog={toggleWarningSubmit}
              onConfirm={handleConfirm}
              variantRightButton="success-light"
            />
          </form>
          {isModalFormOpen && (
            <EditFieldForm
              attributes={attributes}
              fieldForm={fieldForm}
              fieldToEdit={fieldToEdit}
              onChangeEditLabel={handleChangeEditLabel}
              onCloseModal={handleCloseModal}
              onSubmit={handleSubmitFieldEdit}
              type={get(attributes, [fieldToEdit, 'type'], 'text')}
            />
          )}
        </Main>
      </Layout>
    );
  };
  
  ListSettingsView.propTypes = {
    layout: PropTypes.shape({
      uid: PropTypes.string.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,
      options: PropTypes.object.isRequired,
      attributes: PropTypes.objectOf(
        PropTypes.shape({
          type: PropTypes.string,
        })
      ).isRequired,
    }).isRequired,
    slug: PropTypes.string.isRequired,
  };
  
  export default memo(ListSettingsView);
  