Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-admin: how to hide refresh button from AppBar?

I'm creating admin ui based on react-admin and currently searching for a solution to hide the refresh button from the AppBar. Disabling export button was trivial (exporter={false}). Is there anything equally simple for RefreshButton? I couldn't find any working solution.

My React-admin version: 2.9.3

I know you could customize the actions with 'actions' prop on List component, but this seems to be outdated since the Refresh button was moved to the app bar..

I could provide the code to my custom AppBar if needed.

like image 942
Nis Avatar asked Aug 15 '19 14:08

Nis


People also ask

How do I stop auto refresh in react?

Use the preventDefault() method on the event object to prevent a page refresh on form submit in React, e.g. event. preventDefault() . The preventDefault method prevents the browser from issuing the default action which in the case of a form submission is to refresh the page. Copied!

How to filter react admin?

React-admin uses the filter query parameter from the URL to determine the filters to apply to the list. To change the filters, react-admin simply changes this filter query parameter, and the <List> components fetches dataProvider. getList() again with the new filters.

What is AppBar in react JS?

The App Bar displays information and actions relating to the current screen. Material UI for React has this component available for us and it is very easy to integrate. We can use the AppBar Component in ReactJS using the following approach.


3 Answers

There is no simple solution, the presence of the LoadingIndicator component is not configured in AppBar: https://github.com/marmelab/react-admin/blob/master/packages/ra-ui-materialui/src/layout/AppBar.js

You can implement your AppBar component and then connect it to AppLayout:

// Layout.js

import React from 'react';
import { Layout } from 'react-admin';
import AppBarEx from './components/AppBarEx';

const AppLayout = (props) => ( 
  <Layout
    {...props}
    appBar={AppBarEx}
  />
);

export default AppLayout;

// AppBarEx.js

import React, { Children, cloneElement } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import classNames from 'classnames';
import MuiAppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import { withStyles, createStyles } from '@material-ui/core/styles';
import MenuIcon from '@material-ui/icons/Menu';
import withWidth from '@material-ui/core/withWidth';
import compose from 'recompose/compose';
import { toggleSidebar as toggleSidebarAction } from 'ra-core';
import { UserMenu, Headroom } from 'react-admin';

const styles = theme =>
    createStyles({
        toolbar: {
            paddingRight: 24,
        },
        menuButton: {
            marginLeft: '0.5em',
            marginRight: '0.5em',
        },
        menuButtonIconClosed: {
            transition: theme.transitions.create(['transform'], {
                easing: theme.transitions.easing.sharp,
                duration: theme.transitions.duration.leavingScreen,
            }),
            transform: 'rotate(0deg)',
        },
        menuButtonIconOpen: {
            transition: theme.transitions.create(['transform'], {
                easing: theme.transitions.easing.sharp,
                duration: theme.transitions.duration.leavingScreen,
            }),
            transform: 'rotate(180deg)',
        },
        title: {
            flex: 1,
            textOverflow: 'ellipsis',
            whiteSpace: 'nowrap',
            overflow: 'hidden',
        },
    });

const AppBar = ({
    children,
    classes,
    className,
    logo,
    logout,
    open,
    title,
    toggleSidebar,
    userMenu,
    width,
    ...rest
}) => (
    <Headroom>
        <MuiAppBar
            className={className}
            color="secondary"
            position="static"
            {...rest}
        >
            <Toolbar
                disableGutters
                variant={width === 'xs' ? 'regular' : 'dense'}
                className={classes.toolbar}
            >
                <IconButton
                    color="inherit"
                    aria-label="open drawer"
                    onClick={toggleSidebar}
                    className={classNames(classes.menuButton)}
                >
                    <MenuIcon
                        classes={{
                            root: open
                                ? classes.menuButtonIconOpen
                                : classes.menuButtonIconClosed,
                        }}
                    />
                </IconButton>
                {Children.count(children) === 0 ? (
                    <Typography
                        variant="title"
                        color="inherit"
                        className={classes.title}
                        id="react-admin-title"
                    />
                ) : (
                    children
                )}
                {cloneElement(userMenu, { logout })}
            </Toolbar>
        </MuiAppBar>
    </Headroom>
);

AppBar.propTypes = {
    children: PropTypes.node,
    classes: PropTypes.object,
    className: PropTypes.string,
    logout: PropTypes.element,
    open: PropTypes.bool,
    title: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
    toggleSidebar: PropTypes.func.isRequired,
    userMenu: PropTypes.node,
    width: PropTypes.string,
};

AppBar.defaultProps = {
    userMenu: <UserMenu />,
};

const enhance = compose(
    connect(
        state => ({
            locale: state.i18n.locale, // force redraw on locale change
        }),
        {
            toggleSidebar: toggleSidebarAction,
        }
    ),
    withStyles(styles),
    withWidth()
);

export default enhance(AppBar);
like image 193
MaxAlex Avatar answered Oct 04 '22 22:10

MaxAlex


For those of you who just want to hide refresh button, I accomplished it by having my own custom theme (for more info check react admin theming documentation page).

For example, I have two themes, light and dark one. Here is the example of how I managed to target refresh button with css:

 export const lightTheme = {
    palette: {
        background: {
            paper: "#fff",
            default: "#fff"
        },
        primary: {
            main: '#607D8B'
        },
        secondary: {
            main: '#607D8B'
        },
        sidebarColor: '#E7ECEE',
        menuItemsColor: '#4B6471'
    },

// overrides default theme css
    overrides: {
        // targeting refresh button
        RaAppBar: {
            toolbar: {
                '& button': {
                    '&:not(:nth-child(1))': {
                        display: 'none'
                    }
                }
            }
        }
    }
};

It is not pretty way, but for some reason, If you use :nth-child(1) it targets both: drawer (first button in app bar) and custom profile button which is last in html DOM (See the image below).

targeting using :nth-child(1) IMG

Because of that, I come to an idea to use :not((:nth-child(1)) and it solves the problem if your goal is to hide it, but you can also use other css properties to manipulate it.

like image 31
darkoJ Avatar answered Oct 04 '22 22:10

darkoJ


Also less than ideal, but I targeted it with the "Refresh" aria-label. Not an approach I'd typically take, but it's the only thing distinguishing the button in React Admin's CSS.

header.MuiPaper-root button[aria-label="Refresh"] {
  display: none;
}
like image 20
Carlton Avatar answered Oct 04 '22 20:10

Carlton