Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refresh a List View in admin on rest

I am trying to get a list to refresh after a custom action was successfully executed.

i used the saga from the admin on rest tutorial

function * actionApproveSuccess () {
  yield put(showNotification('Executed'))
  yield put(push('/comments')) 
  // does not refresh, because the route does not change
  // react-redux-router also has no refresh() method, like react-router has...
}

the other idea i had was to somehow trigger the refresh action of the list component, but i have no idea how to access that or how to hook that up to the ACTION_SUCCESS event.

like image 709
Jan Johannes Avatar asked Apr 04 '17 16:04

Jan Johannes


4 Answers

There is no way to refresh a route via react router, and that's a known problem. Admin-on-rest's List component has its own refresh mechanism, but offers no API for it.

My advice would be to use a custom <List> component based on admin-on-rest's one. And if you find a way to expose the refresh action, feel free to open a PR on the aor repository!

like image 97
François Zaninotto Avatar answered Nov 17 '22 18:11

François Zaninotto


@Danila Smirnov's answer above shows this message when I use it now:

Deprecation warning: The preferred way to refresh the List view is to connect your custom button with redux and dispatch the refreshView action.

Clicking the refresh button itself wasn't working either nowadays.

Here's the tweaked version that I got working in mine.

Edit: Modified it a bit more to make it reusable.


RefreshListActions.js

import React, { Component } from 'react'
import FlatButton from 'material-ui/FlatButton'
import { CardActions } from 'material-ui/Card'
import NavigationRefresh from 'material-ui/svg-icons/navigation/refresh'
import { connect } from 'react-redux'
import { REFRESH_VIEW } from 'admin-on-rest/src/actions/uiActions'
import { refreshView as refreshViewAction } from 'admin-on-rest/src/actions/uiActions'

class MyRefresh extends Component {
    componentDidMount() {
        const { refreshInterval, refreshView } = this.props
        if (refreshInterval) {
            this.interval = setInterval(() => {
                refreshView()
            }, refreshInterval)
        }
    }

    componentWillUnmount() {
        clearInterval(this.interval)
    }

    render() {
        const { label, refreshView, icon } = this.props;
        return (
            <FlatButton
                primary
                label={label}
                onClick={refreshView}
                icon={icon}
            />
        );
    }
}

const RefreshButton = connect(null, { refreshView: refreshViewAction })(MyRefresh)

const RefreshListActions = ({ resource, filters, displayedFilters, filterValues, basePath, showFilter, refreshInterval }) => (
    <CardActions>
        {filters && React.cloneElement(filters, { resource, showFilter, displayedFilters, filterValues, context: 'button' }) }
        <RefreshButton primary label="Refresh" refreshInterval={refreshInterval} icon={<NavigationRefresh />} />
    </CardActions>
);

export default RefreshListActions

In my list that I want to refresh so often:

import RefreshListActions from './RefreshListActions'

export default (props) => (
    <List {...props}
        actions={<RefreshListActions refreshInterval="10000" />}
        >
        <Datagrid>
            ...
        </Datagrid>
    </List>
)
like image 4
Benjamin Intal Avatar answered Nov 17 '22 16:11

Benjamin Intal


Definitely hacky, but a work-around could be:

push('/comments/1') //any path to change the current route
push('/comments') //the path to refresh, which is now a new route
like image 3
Pim Schaaf Avatar answered Nov 17 '22 18:11

Pim Schaaf


using refreshView action via redux works well.

see example....

import { refreshView as refreshViewAction } from 'admin-on-rest';
import { connect } from 'react-redux'; 

class MyReactComponent extends Component {
  //... etc etc standard react stuff...

 doSomething() {
    // etc etc do smt then trigger refreshView like below  
    this.props.refreshView();
 }
 render() {
   return <div>etc etc your stuff</div>
 }
}

export default connect(undefined, { refreshView: refreshViewAction })(
  MyReactComponent
);
like image 2
Yilmaz Guleryuz Avatar answered Nov 17 '22 18:11

Yilmaz Guleryuz