From b834aea0c921dc5c78edf051c69a75b413cb2a68 Mon Sep 17 00:00:00 2001 From: soupette Date: Tue, 3 Nov 2020 17:07:56 +0100 Subject: [PATCH] Temp commit before layout refacto Signed-off-by: soupette --- .eslintrc.front.js | 1 + .../CollectionTypeRecursivePath/index.js | 6 +- .../admin/src/containers/ListView/index.js | 17 +- .../admin/src/containers/Main/actions.js | 114 +++++---- .../admin/src/containers/Main/constants.js | 12 +- .../admin/src/containers/Main/index.js | 217 ++++++------------ .../admin/src/containers/Main/reducer.js | 135 ++++++----- .../admin/src/containers/Main/selectors.js | 21 +- ...ossibleMainFieldsForModelsAndComponents.js | 2 + 9 files changed, 244 insertions(+), 281 deletions(-) diff --git a/.eslintrc.front.js b/.eslintrc.front.js index afe773c72c..34c0e3a981 100644 --- a/.eslintrc.front.js +++ b/.eslintrc.front.js @@ -124,6 +124,7 @@ module.exports = { 'react/destructuring-assignment': 0, 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }], 'react/forbid-prop-types': 0, + 'react/no-unused-prop-types': 2, 'react/jsx-props-no-spreading': 0, 'react/jsx-one-expression-per-line': 0, 'react/state-in-constructor': 0, diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/CollectionTypeRecursivePath/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/CollectionTypeRecursivePath/index.js index 3246e93fd3..3cc3716885 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/CollectionTypeRecursivePath/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/CollectionTypeRecursivePath/index.js @@ -8,17 +8,17 @@ const EditSettingsView = lazy(() => import('../EditSettingsView')); const ListView = lazy(() => import('../ListView')); const ListSettingsView = lazy(() => import('../ListSettingsView')); -const CollectionTypeRecursivePath = props => { +const CollectionTypeRecursivePath = () => { const { url } = useRouteMatch(); const { slug } = useParams(); const renderRoute = (routeProps, Component) => { - return ; + return ; }; const renderPermissionsRoute = (routeProps, Component) => { return ( - + ); }; diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/ListView/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/ListView/index.js index e0adf3bb01..da3d530b9b 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/ListView/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/ListView/index.js @@ -11,6 +11,7 @@ import { generateFiltersFromSearch, request, CheckPermissions, + useGlobalContext, useUserPermissions, useQuery, } from 'strapi-helper-plugin'; @@ -26,11 +27,12 @@ import { import DisplayedFieldsDropdown from '../../components/DisplayedFieldsDropdown'; import Container from '../../components/Container'; import CustomTable from '../../components/CustomTable'; -import FilterPicker from '../../components/FilterPicker'; + +// import FilterPicker from '../../components/FilterPicker'; import Search from '../../components/Search'; import State from '../../components/State'; import ListViewProvider from '../ListViewProvider'; -import { onChangeListLabels, resetListLabels } from '../Main/actions'; +// import { onChangeListLabels, resetListLabels } from '../Main/actions'; import { AddFilterCta, FilterIcon, Wrapper } from './components'; import Filter from './Filter'; import Footer from './Footer'; @@ -52,11 +54,15 @@ import makeSelectListView from './selectors'; /* eslint-disable react/no-array-index-key */ +const FilterPicker = () =>
FILTER
; +const onChangeListLabels = () => console.log('todo'); +const resetListLabels = () => console.log('todo'); + function ListView({ count, data, didDeleteData, - emitEvent, + // emitEvent, entriesToDelete, isLoading, location: { pathname }, @@ -80,6 +86,7 @@ function ListView({ toggleModalDelete, toggleModalDeleteAll, }) { + const { emitEvent } = useGlobalContext(); const viewPermissions = useMemo(() => generatePermissionsObject(slug), [slug]); const { isLoading: isLoadingForPermissions, @@ -656,7 +663,7 @@ ListView.propTypes = { count: PropTypes.number.isRequired, data: PropTypes.array.isRequired, didDeleteData: PropTypes.bool.isRequired, - emitEvent: PropTypes.func.isRequired, + // emitEvent: PropTypes.func.isRequired, entriesToDelete: PropTypes.array.isRequired, isLoading: PropTypes.bool.isRequired, layouts: PropTypes.object, @@ -664,7 +671,7 @@ ListView.propTypes = { pathname: PropTypes.string.isRequired, search: PropTypes.string.isRequired, }).isRequired, - models: PropTypes.array.isRequired, + // models: PropTypes.array.isRequired, getData: PropTypes.func.isRequired, getDataSucceeded: PropTypes.func.isRequired, history: PropTypes.shape({ diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Main/actions.js b/packages/strapi-plugin-content-manager/admin/src/containers/Main/actions.js index b4603ce8b6..7a7d934111 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/Main/actions.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/Main/actions.js @@ -1,61 +1,75 @@ import { - DELETE_LAYOUT, - DELETE_LAYOUTS, + // DELETE_LAYOUT, + // DELETE_LAYOUTS, + GET_DATA, GET_DATA_SUCCEEDED, - GET_LAYOUT_SUCCEEDED, - ON_CHANGE_LIST_LABELS, - RESET_LIST_LABELS, + // GET_LAYOUT_SUCCEEDED, + // ON_CHANGE_LIST_LABELS, + // RESET_LIST_LABELS, RESET_PROPS, } from './constants'; -export function deleteLayout(uid) { - return { - type: DELETE_LAYOUT, - uid, - }; -} +// export function deleteLayout(uid) { +// return { +// type: DELETE_LAYOUT, +// uid, +// }; +// } -export function deleteLayouts() { - return { - type: DELETE_LAYOUTS, - }; -} +// export function deleteLayouts() { +// return { +// type: DELETE_LAYOUTS, +// }; +// } -export function getDataSucceeded(components, models, mainFields) { - return { - type: GET_DATA_SUCCEEDED, - components, - models: models.filter(model => model.isDisplayed === true), - mainFields, - }; -} +// export function getDataSucceeded(components, models, mainFields) { +// return { +// type: GET_DATA_SUCCEEDED, +// components, +// models: models.filter(model => model.isDisplayed === true), +// mainFields, +// }; +// } -export function getLayoutSucceeded(layout, uid) { - return { - type: GET_LAYOUT_SUCCEEDED, - layout, - uid, - }; -} +// export function getLayoutSucceeded(layout, uid) { +// return { +// type: GET_LAYOUT_SUCCEEDED, +// layout, +// uid, +// }; +// } -export function onChangeListLabels({ target: { name, slug, value } }) { - return { - type: ON_CHANGE_LIST_LABELS, - name, - slug, - value, - }; -} +// export function onChangeListLabels({ target: { name, slug, value } }) { +// return { +// type: ON_CHANGE_LIST_LABELS, +// name, +// slug, +// value, +// }; +// } -export function resetListLabels(slug) { - return { - type: RESET_LIST_LABELS, - slug, - }; -} +// export function resetListLabels(slug) { +// return { +// type: RESET_LIST_LABELS, +// slug, +// }; +// } -export function resetProps() { - return { - type: RESET_PROPS, - }; -} +// export function resetProps() { +// return { +// type: RESET_PROPS, +// }; +// } +// + +export const getData = () => ({ + type: GET_DATA, +}); + +export const getDataSucceeded = (models, components) => ({ + type: GET_DATA_SUCCEEDED, + components, + models, +}); + +export const resetProps = () => ({ type: RESET_PROPS }); diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Main/constants.js b/packages/strapi-plugin-content-manager/admin/src/containers/Main/constants.js index b5c453c663..92672bfc5d 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/Main/constants.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/Main/constants.js @@ -1,7 +1,9 @@ -export const DELETE_LAYOUT = 'ContentManager/Main/DELETE_LAYOUT'; -export const DELETE_LAYOUTS = 'ContentManager/Main/DELETE_LAYOUTS'; +export const GET_DATA = 'ContentManager/Main/GET_DATA'; export const GET_DATA_SUCCEEDED = 'ContentManager/Main/GET_DATA_SUCCEEDED'; -export const GET_LAYOUT_SUCCEEDED = 'ContentManager/Main/GET_LAYOUT_SUCCEEDED'; -export const ON_CHANGE_LIST_LABELS = 'ContentManager/Main/ON_CHANGE_LIST_LABELS'; -export const RESET_LIST_LABELS = 'ContentManager/Main/RESET_LIST_LABELS'; export const RESET_PROPS = 'ContentManager/Main/RESET_PROPS'; + +// export const DELETE_LAYOUT = 'ContentManager/Main/DELETE_LAYOUT'; +// export const DELETE_LAYOUTS = 'ContentManager/Main/DELETE_LAYOUTS'; +// export const GET_LAYOUT_SUCCEEDED = 'ContentManager/Main/GET_LAYOUT_SUCCEEDED'; +// export const ON_CHANGE_LIST_LABELS = 'ContentManager/Main/ON_CHANGE_LIST_LABELS'; +// export const RESET_LIST_LABELS = 'ContentManager/Main/RESET_LIST_LABELS'; diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Main/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/Main/index.js index e658d74341..551c2cf135 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/Main/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/Main/index.js @@ -1,186 +1,105 @@ -import React, { Suspense, lazy, useEffect, useRef } from 'react'; +import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { bindActionCreators, compose } from 'redux'; -import { Switch, Route, useRouteMatch } from 'react-router-dom'; -import { - LoadingIndicatorPage, - useGlobalContext, - request, - CheckPagePermissions, -} from 'strapi-helper-plugin'; +import { Switch, Route } from 'react-router-dom'; +import { LoadingIndicatorPage, request, CheckPagePermissions } from 'strapi-helper-plugin'; import { DndProvider } from 'react-dnd'; import HTML5Backend from 'react-dnd-html5-backend'; import pluginId from '../../pluginId'; import pluginPermissions from '../../permissions'; import DragLayer from '../../components/DragLayer'; import getRequestUrl from '../../utils/getRequestUrl'; -import createPossibleMainFieldsForModelsAndComponents from './utils/createPossibleMainFieldsForModelsAndComponents'; -import { - deleteLayout, - deleteLayouts, - getDataSucceeded, - getLayoutSucceeded, - resetProps, -} from './actions'; +import CollectionTypeRecursivePath from '../CollectionTypeRecursivePath'; +import EditSettingsView from '../EditSettingsView'; +import SingleTypeRecursivePath from '../SingleTypeRecursivePath'; +// import createPossibleMainFieldsForModelsAndComponents from './utils/createPossibleMainFieldsForModelsAndComponents'; +import { getData, getDataSucceeded, resetProps } from './actions'; import makeSelectMain from './selectors'; -const EditSettingsView = lazy(() => import('../EditSettingsView')); -const CollectionTypeRecursivePath = lazy(() => import('../CollectionTypeRecursivePath')); -const SingleTypeRecursivePath = lazy(() => import('../SingleTypeRecursivePath')); - -function Main({ - deleteLayout, - deleteLayouts, - getDataSucceeded, - getLayoutSucceeded, - components, - componentsAndModelsMainPossibleMainFields, - isLoading, - layouts, - location: { pathname }, - global: { currentEnvironment, plugins }, - models, - resetProps, -}) { - const { emitEvent } = useGlobalContext(); - const { - params: { slug }, - } = useRouteMatch('/plugins/content-manager/:contentType/:slug'); - const getDataRef = useRef(); - const getLayoutRef = useRef(); - const resetPropsRef = useRef(); - - getDataRef.current = async () => { - try { - const [{ data: components }, { data: models }] = await Promise.all( - ['components', 'content-types'].map(endPoint => - request(getRequestUrl(endPoint), { method: 'GET' }) - ) - ); - - getDataSucceeded(components, models, { - ...createPossibleMainFieldsForModelsAndComponents(components), - ...createPossibleMainFieldsForModelsAndComponents(models), - }); - } catch (err) { - strapi.notification.error('notification.error'); - } - }; - - getLayoutRef.current = async uid => { - try { - const { data: layout } = await request(getRequestUrl(`content-types/${uid}`), { - method: 'GET', - }); - - getLayoutSucceeded(layout, uid); - } catch (err) { - strapi.notification.error('notification.error'); - } - }; - resetPropsRef.current = resetProps; - - // TODO change the layouts logic - const shouldShowLoader = !pathname.includes('ctm-configurations/') && layouts[slug] === undefined; +// const EditSettingsView = lazy(() => import('../EditSettingsView')); +// const CollectionTypeRecursivePath = lazy(() => import('../CollectionTypeRecursivePath')); +// const SingleTypeRecursivePath = lazy(() => import('../SingleTypeRecursivePath')); +function Main({ getData, getDataSucceeded, isLoading, resetProps }) { useEffect(() => { - getDataRef.current(); + const abortController = new AbortController(); + const { signal } = abortController; + + const fetchData = async signal => { + getData(); + console.log('up'); + + try { + const [{ data: components }, { data: models }] = await Promise.all( + ['components', 'content-types'].map(endPoint => + request(getRequestUrl(endPoint), { method: 'GET', signal }) + ) + ); + + getDataSucceeded(models, components); + } catch (err) { + console.error('CM/main', err); + // TODO: new notif API + strapi.notification.error('notification.error'); + } + }; + + fetchData(signal); return () => { - resetPropsRef.current(); + abortController.abort(); + resetProps(); }; - }, [getDataRef]); + }, [getData, getDataSucceeded, resetProps]); - // This effect is fetching the layout of each content type, however the logic of fetching a specific - // ct has been re introduced in the EditView with the useFetchContentType hook this causes, sometimes, the layout to be fetched twice - // I am leaving this legacy for now and will redo the logic when the back-end when the endpoints for the single types and the collection types will be split - useEffect(() => { - if (shouldShowLoader) { - getLayoutRef.current(slug); - } - }, [getLayoutRef, shouldShowLoader, slug]); - - if (isLoading || shouldShowLoader) { + if (isLoading) { return ; } - const renderRoute = (props, Component) => ( - - ); const routes = [ { path: 'singleType/:slug', comp: SingleTypeRecursivePath }, { path: 'collectionType/:slug', comp: CollectionTypeRecursivePath }, ].map(({ path, comp }) => ( - renderRoute(props, comp)} - /> + )); return ( - }> - - ( - - - - )} - /> - {routes} - - + + + ( + + + + )} + /> + {routes} + ); } Main.propTypes = { - deleteLayout: PropTypes.func.isRequired, - deleteLayouts: PropTypes.func.isRequired, + getData: PropTypes.func.isRequired, getDataSucceeded: PropTypes.func.isRequired, - getLayoutSucceeded: PropTypes.func.isRequired, - global: PropTypes.shape({ - currentEnvironment: PropTypes.string.isRequired, - plugins: PropTypes.object, - }).isRequired, - components: PropTypes.array.isRequired, - componentsAndModelsMainPossibleMainFields: PropTypes.object.isRequired, isLoading: PropTypes.bool.isRequired, - layouts: PropTypes.object.isRequired, - location: PropTypes.shape({ - pathname: PropTypes.string.isRequired, - search: PropTypes.string, - }).isRequired, - models: PropTypes.array.isRequired, resetProps: PropTypes.func.isRequired, }; @@ -189,10 +108,8 @@ const mapStateToProps = makeSelectMain(); export function mapDispatchToProps(dispatch) { return bindActionCreators( { - deleteLayout, - deleteLayouts, + getData, getDataSucceeded, - getLayoutSucceeded, resetProps, }, dispatch diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Main/reducer.js b/packages/strapi-plugin-content-manager/admin/src/containers/Main/reducer.js index d031a1426f..52b30da2f0 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/Main/reducer.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/Main/reducer.js @@ -2,68 +2,97 @@ * * main reducer */ - -import { fromJS } from 'immutable'; +/* eslint-disable consistent-return */ +import produce from 'immer'; import { - DELETE_LAYOUT, - DELETE_LAYOUTS, + // DELETE_LAYOUT, + // DELETE_LAYOUTS, + GET_DATA, GET_DATA_SUCCEEDED, - GET_LAYOUT_SUCCEEDED, - ON_CHANGE_LIST_LABELS, - RESET_LIST_LABELS, + // GET_LAYOUT_SUCCEEDED, + // ON_CHANGE_LIST_LABELS, + // RESET_LIST_LABELS, RESET_PROPS, } from './constants'; +// import { fromJS } from 'immutable'; -export const initialState = fromJS({ - componentsAndModelsMainPossibleMainFields: {}, +const initialState = { + // TODO! + // componentsAndModelsMainPossibleMainFields: {}, + // TODO! components: [], - initialLayouts: {}, isLoading: true, - layouts: {}, models: [], -}); +}; -function mainReducer(state = initialState, action) { - switch (action.type) { - case DELETE_LAYOUT: - return state.removeIn(['layouts', action.uid]); - case DELETE_LAYOUTS: - return state.update('layouts', () => fromJS({})); - case GET_DATA_SUCCEEDED: - return state - .update('components', () => fromJS(action.components)) - .update('models', () => fromJS(action.models)) - .update('componentsAndModelsMainPossibleMainFields', () => - fromJS(action.mainFields) - ) - .update('isLoading', () => false); - case GET_LAYOUT_SUCCEEDED: - return state - .updateIn(['layouts', action.uid], () => fromJS(action.layout)) - .updateIn(['initialLayouts', action.uid], () => fromJS(action.layout)); - case ON_CHANGE_LIST_LABELS: { - const { name, slug, value } = action; - - return state.updateIn( - ['layouts', slug, 'contentType', 'layouts', 'list'], - list => { - if (value) { - return list.push(name); - } - - return list.filter(l => l !== name); - } - ); +const mainReducer = (state = initialState, action) => + produce(state, draftState => { + switch (action.type) { + case GET_DATA: { + draftState.isLoading = true; + break; + } + case GET_DATA_SUCCEEDED: { + draftState.isLoading = false; + draftState.components = action.components; + draftState.models = action.models; + break; + } + case RESET_PROPS: { + draftState = initialState; + break; + } + default: + return draftState; } - case RESET_LIST_LABELS: - return state.updateIn(['layouts', action.slug], () => - state.getIn(['initialLayouts', action.slug]) - ); - case RESET_PROPS: - return initialState; - default: - return state; - } -} + }); + +// export const initialState = fromJS({ +// componentsAndModelsMainPossibleMainFields: {}, +// components: [], +// initialLayouts: {}, +// isLoading: true, +// layouts: {}, +// models: [], +// }); + +// function mainReducer(state = initialState, action) { +// switch (action.type) { +// case DELETE_LAYOUT: +// return state.removeIn(['layouts', action.uid]); +// case DELETE_LAYOUTS: +// return state.update('layouts', () => fromJS({})); +// case GET_DATA_SUCCEEDED: +// return state +// .update('components', () => fromJS(action.components)) +// .update('models', () => fromJS(action.models)) +// .update('componentsAndModelsMainPossibleMainFields', () => fromJS(action.mainFields)) +// .update('isLoading', () => false); +// case GET_LAYOUT_SUCCEEDED: +// return state +// .updateIn(['layouts', action.uid], () => fromJS(action.layout)) +// .updateIn(['initialLayouts', action.uid], () => fromJS(action.layout)); +// case ON_CHANGE_LIST_LABELS: { +// const { name, slug, value } = action; + +// return state.updateIn(['layouts', slug, 'contentType', 'layouts', 'list'], list => { +// if (value) { +// return list.push(name); +// } + +// return list.filter(l => l !== name); +// }); +// } +// case RESET_LIST_LABELS: +// return state.updateIn(['layouts', action.slug], () => +// state.getIn(['initialLayouts', action.slug]) +// ); +// case RESET_PROPS: +// return initialState; +// default: +// return state; +// } +// } export default mainReducer; +export { initialState }; diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Main/selectors.js b/packages/strapi-plugin-content-manager/admin/src/containers/Main/selectors.js index ae7f4200d2..0594f1b5b6 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/Main/selectors.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/Main/selectors.js @@ -2,29 +2,20 @@ import { createSelector } from 'reselect'; import pluginId from '../../pluginId'; import { initialState } from './reducer'; -/** - * Direct selector to the main state domain - */ -const selectMainDomain = () => state => state.get(`${pluginId}_main`) || initialState; - -/** - * Other specific selectors - */ - -/** - * Default selector used by Main - */ +const selectMainDomain = () => state => { + return state.get(`${pluginId}_main`) || initialState; +}; const makeSelectMain = () => createSelector(selectMainDomain(), substate => { - return substate.toJS(); + return substate; }); const makeSelectModels = () => createSelector(selectMainDomain(), substate => { - const allModels = substate.get('models').toJS(); + const { models } = substate; - return allModels.filter(model => model.isDisplayed === true).map(({ uid }) => uid); + return models.filter(model => model.isDisplayed === true).map(({ uid }) => uid); }); export default makeSelectMain; diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Main/utils/createPossibleMainFieldsForModelsAndComponents.js b/packages/strapi-plugin-content-manager/admin/src/containers/Main/utils/createPossibleMainFieldsForModelsAndComponents.js index 65d0845101..d7774702cb 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/Main/utils/createPossibleMainFieldsForModelsAndComponents.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/Main/utils/createPossibleMainFieldsForModelsAndComponents.js @@ -1,3 +1,5 @@ +// TODO + import { get } from 'lodash'; const createPossibleMainFieldsForModelsAndComponents = array => {