First I would like to say that I really appreciate the work you have done with this great framework.
I have an issue with WithPermissionsFilteredChildren. Apparently this component stores the children as state and by that it controls which children are rendered. This makes it is impossible for a component wrapping a e.g List to control the children.
Although there may be reasons of which I'm not aware, I don't feel that a framework should interfere with regular expectations of how React children work. Are there any particular reasons for storing the children as state?
I have made an example of how I would expect it to work in this fiddle: https://jsfiddle.net/activist/L19pgec6/
If you try to do the same (with the respectively named components) in admin-on-rest the second child/paragraph will render even though the wrapping component removes it.
Any thoughts on this? Would it be possible to rewrite this part of the code? Or if the children must be stored as state, could a callback possibly be provided to update the children state?
Also see https://stackoverflow.com/questions/46606712/is-there-a-simple-way-of-implementing-a-column-picker-for-a-list for relevant example.
Environment
Have you tried the function as a child pattern here ? See restricting-access-to-fields-and-inputs in the documentation. In the 2.0.0 version, you won't have to use an authClient for this to work. In the mean time, just implement a dummy one if needed
In any case, please provide a small repository reproducing the issue
I tried to use the function as child pattern, but it didn't really make any difference (or at least I was unable to make it work). My theory is that the children are never updated after initial render since children are being set as state in WIthPermissionsFilteredChildren's componentDidMount which only runs once. I cannot find any place where they are "updated" after that.
I added a fork of the admin-on-rest-demo here: https://github.com/activist/admin-on-rest-demo
Check out the "Orders" section where I have wrapped the original Command-list with a "ColumnPickableList" which in turns manipulates which children should be rendered.
As a sidenote I can also see that the ColumnpickableList is messing up the sort functionality of the List, but I haven't been able to look more into it yet.
@activits I don't understand what you're trying to do, can you elaborate?
@fzaninotto I have a table with so many columns so that horizontal scrolling occurs. My usecase is that I want to dynamically control which columns in a List are displayed based on some condition. For my scenario this condition is a set of checkboxes (one per column) that when unchecked, the column(s) is dynamically removed/hidden from the table.
But with the current implementation of List (and WithPermissionsFilteredChildren) this is impossible as the List children are stored as state in WithPermissionsFilteredChildren in componentDidMount. In addition to the above fork I have made a small fiddle here where you can see how it should work (or at least how I would expect it to work using regular React components). For the sake of the example the components in the JSFiddle have the same names as the AOR respective components used in the above fork. Let me know if you need more information.
Understood. So I guess the fix is to add a componentWillReceiveProps method to WithPermissionsFilteredChildren.
Yes, that would probably work if the initializeChildrenfunction is called again or the state is updated with the new children in componentWillReceiveProps.
I figured out a workaround to this issue which works bypassing the List and instead adding the columnpicker as a wrapper around the Datagrid. That introduces some challenges with respect to placement of the columnpicker, but at least it keeps the "children as state" in List.js out of scope and controlling which children (and thus which columns) are rendered is possible..
@activist Can you share an example of that? We're trying to do something similar with a Column Selector. We have a components object and loop through them in DataGrid. If the key is in the reducer values, it will render the component. This worked in 1.2.X but does not update in 1.3.X when the column reducer values change.
const components = {
id: (props) => <TextField source="id" />
}
<DataGrid>
{ this.props.values.map(value => components[value](this.props)) }
</DataGrid>
The workaround I have only tested with the current master, so I actually cannot confirm that it works with e.g 1.3.x yet. I will try to make time for it this evening.
Regarding the approach it is slightly different than yours. It is basically what I cooked together for this bug: https://github.com/activist/admin-on-rest-demo/blob/master/src/columnpicker/columnpickablelist.js
Just note that as stated above the workaround for my case seems to be to let the ColumnpickableList wrap the Datagrid directly so that the render method would be like this (i.e List is commented out by intent):
...
removeHiddenColumns(children) {
return React.Children.map(children, (child) => {
if (!child.props.source) {
return child;
}
const column = this.props.columnsDisplayed.find((columnDisplayed) => {
return columnDisplayed.source === child.props.source;
});
if (this.props.columnsDisplayed.length === 0 || (column && column.checked)) {
return child;
}
return null;
});
}
render() {
const { children, ...rest } = this.props;
const childrenToRender = this.removeHiddenColumns(children);
return (
<div className="columnpickable-list">
<ColumnPicker columns={this.props.columnsDisplayed} onCheckboxChanged={this.props.handleCheckboxChanged} />
{ /* <List {...rest}> */ }
<Datagrid>
{childrenToRender}
</Datagrid>
{ /* </List> */ }
</div>
);
}
@danejorgensen I'm not sure if it is exactly what you need, but I have added a proof-of-concept here: https://github.com/activist/admin-on-rest-demo/tree/datagrid_columnpicker
It works with admin.on-rest 1.3.2. You can see the columnpicker when running the demo and open the 'Orders' page.
@activist thanks, that looks great. I'm going to try to get your version working with permissions as well. We have some columns that only an admin should see in DataGrid and the ColumnPicker.
I think we have the same problem :(
cf. https://stackoverflow.com/questions/46979716/components-seems-to-be-not-re-rendered
Hi,
I am facing an issue, wich seems to be linked to the same root cause.
I want update a custom component embbed inside a <Show> component, but this is never updated.
The component is rerendering,but the props is updated.
Originally my custom component was inside a <SimpleShowLayout>, but the problem seems s to be at any level below Show
Most helpful comment
I think we have the same problem :(
cf. https://stackoverflow.com/questions/46979716/components-seems-to-be-not-re-rendered