-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DataGrid] Allow to control the columns visibility #3554
[DataGrid] Allow to control the columns visibility #3554
Conversation
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if by allowing the visible columns to be controlled it won't conflict with other features in the future. I remember that with editRowsModel
it caused a lot of problems, since we lost the warranty that the value would be updated synchronously. Now we may need to wait for the next render.
Should visibleColumnsModel
receive an object where each key value is true
(visible) or false
(hidden)? It could be renamed to columnVisibilityModel
in this case. With an array, it becomes a pain to hide a specific column. Also, the object doesn't require all fields to be present. Users might be upset when we drop hide
and require them to pass all the visible fields.
I noticed a bug if I have checkboxSelection={false}
then I change it to checkboxSelection={true}
. The checkbox column is never visible nor onVisibleColumnsModelChange
is called. See this CodeSandbox.
it('should update `visibleColumnsModel` but not `GridColDef.hide` in state', () => { | ||
render(<TestDataGridPro initialState={{ columns: { visibleColumnsModel: ['id'] } }} />); | ||
apiRef.current.setColumnVisibility('id', false); | ||
expect(apiRef.current.state.columns.lookup.id.hide).to.equal(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't be making assertions on the state, they may change while yielding the same result for the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can listen to columnChange
events to get the same result if we really want to avoid state assertions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also check if columnVisibilityChange
was not called. My point is that we don't recommend direct state access, but to use selectors or API methods instead. That way, the test should ensure that if someone access the state via one of the recommended ways it will return the correct value. We shouldn't be testing the internal implementation, but what is one the public API or can be seen (UI).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I'll use the selector.
It won't impact the end user but users that use the selectors could have problems if we update the hide
field by mistake.
packages/grid/x-data-grid-pro/src/tests/columnsVisibility.DataGridPro.test.tsx
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid/src/tests/columnsVisibility.DataGrid.test.tsx
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid/src/tests/columnsVisibility.DataGrid.test.tsx
Outdated
Show resolved
Hide resolved
packages/grid/x-data-grid/src/tests/columnsVisibility.DataGrid.test.tsx
Outdated
Show resolved
Hide resolved
@@ -147,9 +147,9 @@ describe('<DataGrid /> - Layout & Warnings', () => { | |||
|
|||
it('should support columns.valueGetter using `getValue` (deprecated)', () => { | |||
const columns = [ | |||
{ field: 'id', hide: true }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this test be reverted to ensure that the old API still works?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As valueGetter
is deprecated, I chose to switch this test to the new behavior without keeping the old one.
But I could duplicate it and test both valueGetter
+ hide
and valueGetter
+ columnVisibilityModel
.
I feel like this one is closer to the other model we already have like
It is one of the main point I would like to discuss yes. |
Yeah, once method or UI try to update the model we stop any further action. The side effects should be handled inside an effect to avoid the problems of
I'm in favor of using an object to ease the transition for users. Internally, the array is converted to an object, so there's one step we can remove here. In the case of |
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
useGridStateInit(apiRef, (state) => { | ||
const columnsState = createColumnsState({ | ||
apiRef, | ||
columnsTypes, | ||
columnsToUpsert: props.columns, | ||
shouldRegenColumnVisibilityModelFromColumns: !shouldUseVisibleColumnModel, | ||
currentColumnVisibilityModel: | ||
props.columnVisibilityModel ?? props.initialState?.columns?.columnVisibilityModel ?? {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default, the id column in the Commodity dataset is hidden. However, in https://deploy-preview-3554--material-ui-x.netlify.app/components/data-grid/columns/#column-visibility, all demos that use this dataset and have an initial state or the columnVisibilityModel
prop, the id column is visible. With that being said, should the initial state be created also from the columns with hide
? In controlled mode I guess there's nothing we can do, unless include the id column in the object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should hide manually the id
column on the demo I think.
I would advise against using the hide
field when the model is defined. The way I built it, the hide
field is deprecated. If we use the model, it is not taken into account at all.
That way it is not breaking, but users won't be able to do dirty tricks with both the hide
and models
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the brokerId column is also hidden in the dataset. This makes me think if wouldn't be better to include a default initialState={{ columns: { columnVisibilityModel: { id: false } } }}
below. Once we drop hide
it will break all demos.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Demo will have to manually pass it to the initialState
when they override it
But yes better do it now, we will forget if we don't
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it planned to remove the shouldUseVisibleColumnModel
in v6?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, in v6 we would always use the model, the hide
field would not exist anymore.
Co-authored-by: Matheus Wichman <matheushw@outlook.com>
Co-authored-by: Matheus Wichman <matheushw@outlook.com>
Co-authored-by: Matheus Wichman <matheushw@outlook.com>
Co-authored-by: Matheus Wichman <matheushw@outlook.com>
I have 2 Argos diff, I will try to fix them tomorrow |
packages/grid/_modules_/grid/components/panel/GridColumnsPanel.tsx
Outdated
Show resolved
Hide resolved
packages/grid/_modules_/grid/hooks/features/columns/gridColumnsUtils.ts
Outdated
Show resolved
Hide resolved
useGridStateInit(apiRef, (state) => { | ||
const columnsState = createColumnsState({ | ||
apiRef, | ||
columnsTypes, | ||
columnsToUpsert: props.columns, | ||
shouldRegenColumnVisibilityModelFromColumns: !shouldUseVisibleColumnModel, | ||
currentColumnVisibilityModel: | ||
props.columnVisibilityModel ?? props.initialState?.columns?.columnVisibilityModel ?? {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it planned to remove the shouldUseVisibleColumnModel
in v6?
Closes #2198
Closes #1412
Part of #3448
Goals
Allow to control the visible columns just like the other models
visibleColumnsModel
+onVisibleColumnsModelChange
Do not break existing code with
GridColDef.hide
even for users switching manually the visibility withapiRef.current.updateColumns
(add a temporary sync from the columns to the model)Advancement
visibleColumnsModel
andonVisibleColumnsModelChange
visibleColumnsModel
is not controlled, generate it fromGridColDef.hide
visibleColumnsModel
to theinitialState
prop (for [DataGrid] Add other sub-states to theinitialState
prop #3448)onColumnVisibilityChange
and only use it when the update comes fromGridColDef.hide
GridColDef.hide
GridColDef.hide
to also test with the modelRelease note
🙈 Allow to control the columns visibility ([DataGrid] Allow to control the columns visibility #3554) @flaviendelangle
See the documentation for more details.
The
hide
property fromGridColDef
still works but has been deprecated.