user2078023
user2078023

Reputation: 1266

Admin on Rest: How can we preserve a query param between

We have a need where 3 different menu items perform CRUD operations to the same resource ("assets"), but with just the category_id being different on all CRUD operations (until you press again a different menu item).

In order to do this, we introduced a query param, called kind, which is the only practical difference among these 3 links:

    <MenuItemLink
        to={{
            pathname: '/assets',
            search: stringify({page: 1, perPage: 25}),
        }}
        primaryText="Assets" 
        onClick={onMenuTap} 
        leftIcon={<AssetsIcon />} 
    />

    <MenuItemLink
        to={{
            pathname: '/assets',
            search: stringify({
                page: 1,
                perPage: 25,
                kind: 'printers'
            }),
        }}
        primaryText="Printers"
        onClick={onMenuTap}
        leftIcon={<AssetsIcon />}
    />

    <MenuItemLink
        to={{
            pathname: '/assets',
            search: stringify({
                page: 1,
                perPage: 25,
                kind: 'vehicles'
            }),
        }}
        primaryText="Vehicles"
        onClick={onMenuTap}
        leftIcon={<AssetsIcon />}
    />

Through the following code, the List fetches records only for these assets:

// NOTE: 'parsedKind' is parsed grom query params with previous code, it gets one of these values: '' OR 'printers' OR 'vehicles'

    <List
        title={<TitleList location={props.location} />}
        {...props}
        filters={<AssetFilter location={props.location} key={parsedKind} />}
        perPage={15}
        filter={{cat_id: dbIds[parsedKind]}}
        sort={{field: 'name', order: 'ASC'}}
        actions={<OurCustomListActions parsedKind={parsedKind} {...props} />}
        key={parsedKind}
    >

In order for this to work we had to customize the "actions" with custom Buttons, so that the parsedKindis following through. For example, the CreateButton now needs a prop ourQuery:

   <FlatButton
        primary
        label={label && translate(label)}
        icon={<ContentAdd />}
        containerElement={<Link to={`${basePath}/create?${ourQuery}`} />}
        style={styles.flat}
    />

I have 3 questions here:

  1. This was a tedious work (all buttons have been customized) and I wonder if there was another solution to cover this need.

  2. Still, the "SaveButton" causes headaches, because it uses a handleSubmitWithRedirect function that comes from props and the parameter is just the name of the view ('list' for example). So how can I add the query param on the final URL there? I used an ugly setTimeout to do this after 2 seconds (window.location.hash = window.location.hash + '?' + this.props.ourQuery;) but obviously this is very wrong. The DeleteButtonis also problematic because it redirects to a subview.

  3. Using the above approach I get NaN-NaN from 19 in the List pagination. Why? Can this also be solved somehow?

Thank you!

Upvotes: 0

Views: 693

Answers (1)

Dennie de Lange
Dennie de Lange

Reputation: 2934

So I think your best bet would have been to simply create three resources: Assets, Vehicles and Printers. Than in your restClient/dataProvider, create logic to route these three resources to the assets endpoint with the correct parameter. I simple middleware would suffice, something in the line off:

// MyAssetResourceMiddleware.js
export default restClient => (type, resource, params) => {
     switch(resource){
        case 'Assets':
        case 'Vehicles':
        case 'Printers':
          return restClient(type,'assets',{...params,kind:resource});
        default: 
          return restClient(type,resource,params);
     }    
}

And wrap your provider with it

<Admin dataProvider={MyAssetResourceMiddleware(dataProvider)} .../>

Upvotes: 1

Related Questions