React-admin: custom Layout code doesn't work with 1.3.0 for Menu and Sidebar

Created on 14 Sep 2017  路  13Comments  路  Source: marmelab/react-admin

With this code: https://marmelab.com/admin-on-rest/Theming.html#using-a-custom-layout

I am getting:

image

if I change the propType of menu to be funcinstead of element

I get one of the two errors:

image

and if import Menu
and put it in <Sidebar><Menu/></Sidebar>

I get a menu that doesn't work for all the paths that are connected to resources (e.g List) but works for the routes file ones. Logout doesn't show up either

image

with extra errors:

image

due to <WithPermission> around <MenuItem>s

bug

All 13 comments

Can you provide a repository showcasing the problem?

@djhi I could replicate the broken Menu behavior without changing the Layout code but without getting the error that breaks the whole application.. there seems to be an additional problem with WithPermission and MenuItems as well. Please see my only commit after fork

https://github.com/zifnab87/admin-on-rest-demo

We had to refactor quite a lot of code for the aor-permissions integration into the core package. The documentation is indeed misleading. Until we update it, I suggest you look at the new layout code, especially the usage of the AdminRoutes component.

Thanks @djhi I tried replacing my Layout with this:

import React, { createElement, Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import autoprefixer from 'material-ui/utils/autoprefixer';
import CircularProgress from 'material-ui/CircularProgress';
import withWidth from 'material-ui/utils/withWidth';
import compose from 'recompose/compose';
import customTheme from './customTheme';
import AdminRoutes from 'admin-on-rest';
import { AppBar ,Sidebar, Menu, Notification } from 'admin-on-rest';
import { setSidebarVisibility as setSidebarVisibilityAction } from 'admin-on-rest';

const styles = {
    wrapper: {
        // Avoid IE bug with Flexbox, see #467
        display: 'flex',
        flexDirection: 'column',
    },
    main: {
        display: 'flex',
        flexDirection: 'column',
        minHeight: '100vh',
    },
    body: {
        backgroundColor: '#edecec',
        display: 'flex',
        flex: 1,
        overflowY: 'hidden',
        overflowX: 'scroll',
    },
    bodySmall: {
        backgroundColor: '#fff',
    },
    content: {
        flex: 1,
        padding: '2em',
    },
    contentSmall: {
        flex: 1,
        paddingTop: '3em',
    },
    loader: {
        position: 'absolute',
        top: 0,
        right: 0,
        margin: 16,
        zIndex: 1200,
    },
};

const prefixedStyles = {};

class Layout extends Component {
    componentWillMount() {
        if (this.props.width !== 1) {
            this.props.setSidebarVisibility(true);
        }
    }

    render() {
        const {
            children,
            customRoutes,
            dashboard,
            isLoading,
            logout,
            menu,
            catchAll,
            theme,
            title,
            width,
        } = this.props;

        const muiTheme = getMuiTheme(theme);
        if (!prefixedStyles.main) {
            // do this once because user agent never changes
            const prefix = autoprefixer(muiTheme);
            prefixedStyles.wrapper = prefix(styles.wrapper);
            prefixedStyles.main = prefix(styles.main);
            prefixedStyles.body = prefix(styles.body);
            prefixedStyles.bodySmall = prefix(styles.bodySmall);
            prefixedStyles.content = prefix(styles.content);
            prefixedStyles.contentSmall = prefix(styles.contentSmall);
        }
        return (
            <MuiThemeProvider muiTheme={muiTheme}>
                <div style={prefixedStyles.wrapper}>
                    <div style={prefixedStyles.main}>
                        {width !== 1 && <AppBar title={title} />}
                        <div
                            className="body"
                            style={
                                width === 1 ? (
                                    prefixedStyles.bodySmall
                                ) : (
                                    prefixedStyles.body
                                )
                            }
                        >
                            <div
                                style={
                                    width === 1 ? (
                                        prefixedStyles.contentSmall
                                    ) : (
                                        prefixedStyles.content
                                    )
                                }
                            >
                                <AdminRoutes
                                    customRoutes={customRoutes}
                                    dashboard={dashboard}
                                    catchAll={catchAll}
                                >
                                    {children}
                                </AdminRoutes>
                            </div>
                            <Sidebar theme={theme}>
                                {createElement(menu || Menu, {
                                    logout,
                                    hasDashboard: !!dashboard,
                                })}
                            </Sidebar>
                        </div>
                        <Notification />
                        {isLoading && (
                            <CircularProgress
                                className="app-loader"
                                color="#fff"
                                size={width === 1 ? 20 : 30}
                                thickness={2}
                                style={styles.loader}
                            />
                        )}
                    </div>
                </div>
            </MuiThemeProvider>
        );
    }
}

const componentPropType = PropTypes.oneOfType([
    PropTypes.func,
    PropTypes.string,
]);

Layout.propTypes = {
    children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
    catchAll: componentPropType,
    customRoutes: PropTypes.array,
    dashboard: componentPropType,
    isLoading: PropTypes.bool.isRequired,
    logout: PropTypes.oneOfType([
        PropTypes.node,
        PropTypes.func,
        PropTypes.string,
    ]),
    menu: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
    setSidebarVisibility: PropTypes.func.isRequired,
    title: PropTypes.node.isRequired,
    theme: PropTypes.object.isRequired,
    width: PropTypes.number,
};

Layout.defaultProps = {
    theme: customTheme,
};

function mapStateToProps(state) {
    return {
        isLoading: state.admin.loading > 0,
    };
}

const enhance = compose(
    connect(mapStateToProps, {
        setSidebarVisibility: setSidebarVisibilityAction,
    }),
    withWidth()
);

export default enhance(Layout);

and I still get errors and my app doesn't load

image

Here is my customTheme:

import {
  cyan500, cyan700,
  pinkA200,
  grey100, grey300, grey400, grey500,
  white, darkBlack, fullBlack,
} from 'material-ui/styles/colors';
import { fade } from 'material-ui/utils/colorManipulator';
import spacing from 'material-ui/styles/spacing';

const customTheme = {
    spacing: spacing,
    fontFamily: 'Roboto, sans-serif',
    borderRadius: 2,
    palette: {
      primary1Color: 'rgb(25,64,130)',
      primary2Color: cyan700,
      primary3Color: grey400,
      accent1Color: pinkA200,
      accent2Color: grey100,
      accent3Color: grey500,
      textColor: darkBlack,
      alternateTextColor: white,
      canvasColor: white,
      borderColor: grey300,
      disabledColor: fade(darkBlack, 0.3),
      pickerHeaderColor: cyan500,
      clockCircleColor: fade(darkBlack, 0.07),
      shadowColor: fullBlack,
    },
    appBar: {
      color: white,
    },
};

export default customTheme;

Here is my customRoutes:


import React from 'react';
import { Route } from 'react-router-dom';
import Charts from './Charts';

export default [
    <Route exact path="/charts" component={Charts} />,
];

I made your repository work on my machine. I will commit it tomorrow

@djhi Thanks!! I am curious to see them!

I even tried those changes: https://github.com/marmelab/admin-on-rest-demo/commit/5df872fadac85906afd5e7d563d8a5c6c9b0d435 - routing seems to be still broken entirely
and it makes my Menu completely disappear with or without the changes in custom Layout. I wonder how Menu problems is making routing problematic too

I can't push my commit: not authorized

However, if you only want to update the theme, you should check the documentation.

Anyway, I'm closing this as this is not a bug but rather a need for help debugging some code. Please continue to StackOverflow if needed.

@djhi I added you as a collaborator! Thanks!

Nope, still can't

@djhi I have invited you but you haven't accepted yet

image

Pushed. I forgot I had to accept invitations :tired_face:

@djhi Haha :) Thanks for your effort! Menu seems to work with your commit (here for quick ref: https://github.com/zifnab87/admin-on-rest-demo/commit/bdcbe7bdf48ea178f110446ecf8d6d9944b6f4d4) though WithPermissions around each MenuItemLink I get two warnings as I stated in the first comment (extra errors). Should I make a new issue for that?

I am going to migrate those changes to my other project and see if there are still issues with editButton with Permissions that was automatically closed from aor-permissions

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Weakky picture Weakky  路  20Comments

MhdSyrwan picture MhdSyrwan  路  24Comments

fzaninotto picture fzaninotto  路  27Comments

xiaomingplus picture xiaomingplus  路  22Comments

keulu-ing picture keulu-ing  路  22Comments