-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Made each taxonomy appear on its own panel. #5183
Made each taxonomy appear on its own panel. #5183
Conversation
34d4832
to
adb8217
Compare
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.
Seeing key warning:
react.0406e355.js:336 Warning: Each child in an array or iterator should have a unique "key" prop.
Check the render method of
PostTaxonomies
. See https://fb.me/react-warning-keys for more information.
function TaxonomyPanel( { taxonomy, isOpened, onTogglePanel, panelName, children } ) { | ||
const taxonomyMenuName = get( taxonomy, [ 'labels', 'menu_name' ] ); | ||
if ( ! taxonomyMenuName ) { | ||
return; |
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.
A component cannot return undefined
from its render. It should return null
.
} | ||
return ( | ||
<PanelBody | ||
key={ panelName } |
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 don't think key
is effective in this context?
return toggleGeneralSidebarEditorPanel( panelName ); | ||
}, | ||
}, | ||
( stateProps, dispatchProps, ownProps ) => { |
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.
See #5090 and #5098 (comment) for more on my distaste for the mergeProps
function. Specifically that returning a function here will cause the component to always re-render. Via withDispatch
of #5137, we can probably avoid this now.
}; | ||
}, | ||
{ | ||
onTogglePanel( panelName ) { |
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.
Minor: This could be simplified to:
{
onTogglePanel: toggleGeneralSidebarEditorPanel,
},
@@ -171,7 +171,6 @@ class FlatTermSelector extends Component { | |||
|
|||
return ( | |||
<div className="editor-post-taxonomies__flat-terms-selector"> |
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.
Do we need the wrapper anymore?
I see there's a lingering style for it, but I'm wondering if we need that either:
Why doesn't .components-panel__body-title
add its own bottom margin rather than rely on children to add this themselves?
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 totally agree with your comment .components-panel__body-title should add its own margin. I wanted to avoid that because it would be a change that affected all the application. But I checked that in inspector controls there was a rule that added this margin. So I removed the rule from there and added it to the component. The changes should be unnoticeable but allowed to remove the wrappers as suggested 👍
); | ||
} ); | ||
|
||
// Fragment is used because enzyme shallow does not seems to handle correctly components returning just arrays. |
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.
Are you sure it's not just that shallow
won't traverse into the children
? Have you tried with mount
instead?
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.
Not sure of the reason but all my tries to test the component returning an array failed and I observed that the debug method returned totally invalid data. At the time I found a recent PR on enzyme repository, related to this enzymejs/enzyme#1498, maybe these changes are not yet available in our version.
I also tried to use mount instead, but unfortunately, it was not possible because of errors related with our withAPIData HOC I think we would need to mock it to use mount here, which was something unnecessary for testing purposes of this component.
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.
It's very unintuitive, but this seemed to work okay for me:
diff --git a/editor/components/post-taxonomies/index.js b/editor/components/post-taxonomies/index.js
index d7f28db94..200d61f06 100644
--- a/editor/components/post-taxonomies/index.js
+++ b/editor/components/post-taxonomies/index.js
@@ -8,7 +8,7 @@ import { filter, identity, includes } from 'lodash';
* WordPress dependencies
*/
import { withAPIData } from '@wordpress/components';
-import { compose, Fragment } from '@wordpress/element';
+import { compose } from '@wordpress/element';
/**
* Internal dependencies
@@ -20,7 +20,8 @@ import { getCurrentPostType } from '../../store/selectors';
export function PostTaxonomies( { postType, taxonomies, taxonomyWrapper = identity } ) {
const availableTaxonomies = filter( taxonomies.data, ( taxonomy ) => includes( taxonomy.types, postType ) );
- const taxonomyComponents = availableTaxonomies.map( ( taxonomy ) => {
+
+ return availableTaxonomies.map( ( taxonomy ) => {
const TaxonomyComponent = taxonomy.hierarchical ? HierarchicalTermSelector : FlatTermSelector;
return taxonomyWrapper(
<TaxonomyComponent
@@ -31,14 +32,6 @@ export function PostTaxonomies( { postType, taxonomies, taxonomyWrapper = identi
taxonomy
);
} );
-
- // Fragment is used because enzyme shallow does not seems to handle correctly components returning just arrays.
- // Using debug method it was possible to verify shallow always output <undefined /> when arrays are used.
- return (
- <Fragment>
- { taxonomyComponents }
- </Fragment>
- );
}
const applyConnect = connect(
diff --git a/editor/components/post-taxonomies/test/index.js b/editor/components/post-taxonomies/test/index.js
index 42cfed70f..1f21845a1 100644
--- a/editor/components/post-taxonomies/test/index.js
+++ b/editor/components/post-taxonomies/test/index.js
@@ -16,7 +16,7 @@ describe( 'PostTaxonomies', () => {
<PostTaxonomies postType="page" taxonomies={ taxonomies } />
);
- expect( wrapper.children() ).toHaveLength( 0 );
+ expect( wrapper.at( 0 ) ).toHaveLength( 0 );
} );
it( 'should render taxonomy components for taxonomies assigned to post type', () => {
@@ -43,8 +43,8 @@ describe( 'PostTaxonomies', () => {
<PostTaxonomies postType="page" taxonomies={ taxonomies } />
);
- expect( wrapper.children() ).toHaveLength( 1 );
- expect( wrapper.childAt( 0 ).props() ).toEqual( {
+ expect( wrapper.at( 0 ) ).toHaveLength( 1 );
+ expect( wrapper.at( 0 ).at( 0 ).props() ).toEqual( {
slug: 'category',
restBase: 'categories',
} );
enzymejs/enzyme#1149 is the (open) parent issue for array-returning components in Enzyme.
ecb5243
to
db17ed3
Compare
withDispatch( ( dispatch, ownProps ) => ( { | ||
onTogglePanel: () => { | ||
if ( ownProps.panelName ) { | ||
return dispatch( 'core/edit-post' ). |
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.
This doesn't need to return a value.
onTogglePanel: () => { | ||
if ( ownProps.panelName ) { | ||
return dispatch( 'core/edit-post' ). | ||
toggleGeneralSidebarEditorPanel( ownProps.panelName ); |
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.
Minor: If we're concerned about line length, we could invert the condition to an early return to avoid the tab.
if ( ! ownProps.panelName ) {
return;
}
dispatch( 'core/edit-post' ).toggleGeneralSidebarEditorPanel( ownProps.panelName );
} ), | ||
withDispatch( ( dispatch, ownProps ) => ( { | ||
onTogglePanel: () => { | ||
if ( ownProps.panelName ) { |
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.
Under what real-world conditions will panelName
be falsey? And in those cases, is it acceptable that toggling the panel then does nothing?
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 expected when loading, but on a second thought when loading the array is empty and we don't render taxonomy-panel at all, so this logic was not needed.
); | ||
} ); | ||
|
||
// Fragment is used because enzyme shallow does not seems to handle correctly components returning just arrays. |
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.
It's very unintuitive, but this seemed to work okay for me:
diff --git a/editor/components/post-taxonomies/index.js b/editor/components/post-taxonomies/index.js
index d7f28db94..200d61f06 100644
--- a/editor/components/post-taxonomies/index.js
+++ b/editor/components/post-taxonomies/index.js
@@ -8,7 +8,7 @@ import { filter, identity, includes } from 'lodash';
* WordPress dependencies
*/
import { withAPIData } from '@wordpress/components';
-import { compose, Fragment } from '@wordpress/element';
+import { compose } from '@wordpress/element';
/**
* Internal dependencies
@@ -20,7 +20,8 @@ import { getCurrentPostType } from '../../store/selectors';
export function PostTaxonomies( { postType, taxonomies, taxonomyWrapper = identity } ) {
const availableTaxonomies = filter( taxonomies.data, ( taxonomy ) => includes( taxonomy.types, postType ) );
- const taxonomyComponents = availableTaxonomies.map( ( taxonomy ) => {
+
+ return availableTaxonomies.map( ( taxonomy ) => {
const TaxonomyComponent = taxonomy.hierarchical ? HierarchicalTermSelector : FlatTermSelector;
return taxonomyWrapper(
<TaxonomyComponent
@@ -31,14 +32,6 @@ export function PostTaxonomies( { postType, taxonomies, taxonomyWrapper = identi
taxonomy
);
} );
-
- // Fragment is used because enzyme shallow does not seems to handle correctly components returning just arrays.
- // Using debug method it was possible to verify shallow always output <undefined /> when arrays are used.
- return (
- <Fragment>
- { taxonomyComponents }
- </Fragment>
- );
}
const applyConnect = connect(
diff --git a/editor/components/post-taxonomies/test/index.js b/editor/components/post-taxonomies/test/index.js
index 42cfed70f..1f21845a1 100644
--- a/editor/components/post-taxonomies/test/index.js
+++ b/editor/components/post-taxonomies/test/index.js
@@ -16,7 +16,7 @@ describe( 'PostTaxonomies', () => {
<PostTaxonomies postType="page" taxonomies={ taxonomies } />
);
- expect( wrapper.children() ).toHaveLength( 0 );
+ expect( wrapper.at( 0 ) ).toHaveLength( 0 );
} );
it( 'should render taxonomy components for taxonomies assigned to post type', () => {
@@ -43,8 +43,8 @@ describe( 'PostTaxonomies', () => {
<PostTaxonomies postType="page" taxonomies={ taxonomies } />
);
- expect( wrapper.children() ).toHaveLength( 1 );
- expect( wrapper.childAt( 0 ).props() ).toEqual( {
+ expect( wrapper.at( 0 ) ).toHaveLength( 1 );
+ expect( wrapper.at( 0 ).at( 0 ).props() ).toEqual( {
slug: 'category',
restBase: 'categories',
} );
enzymejs/enzyme#1149 is the (open) parent issue for array-returning components in Enzyme.
436b007
to
8e8e91d
Compare
Hi @aduth thank you for providing a possible approach to handle enzyme array limitation 👍, all the feedback was applied. |
I'd like for this to make it into the 2.3 release, but am also wary about the small design change here in that there's marginally more margin added to the bottom of sidebar panel titles. The removed styles applied only to block inspector panels, not those in the document inspector
cc @jasmussen |
const TaxonomyComponent = taxonomy.hierarchical ? HierarchicalTermSelector : FlatTermSelector; | ||
return taxonomyWrapper( | ||
<TaxonomyComponent | ||
key={ taxonomy.slug } |
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 think there's some redundancy in key
application. Technically this prop is not needed (nor used), but I do think it should be the responsibility of this component, not the callback for taxonomyWrapper
, to apply the key
. This could be done in one of two ways:
- Add a wrapper element to the return value of this
map
callback with thekey
- Use
cloneElement
to assignkey
as a prop into the return value oftaxonomyWrapper
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, it makes sense to define the key here, I used a wrapper as it looks like the simplest approach.
...this.renderTerms( availableTermsTree ), | ||
! loading && ( | ||
<button | ||
key="term-add-btn" |
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.
Minor: Abbreviating seems to serve only to introduce some ambiguity here.
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.
The abbreviation was removed.
required | ||
/> | ||
{ !! availableTerms.length && | ||
<TreeSelect |
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 be indented one more (how it was previously)
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.
Corrected.
Took a look. Here's the whole panel: Here's the extra margin the change makes: I think this is fine. 👍 👍 for the change and shipping, we can always revisit later. Now that you made me look, however, and this is unrelated to this PR, I did notice that there's too much padding in the Status and Comments panels: This seems to be from the We can either convert that margin to a bottom margin instead, or do something like this:
That would address it: But this can be done separately. |
8e8e91d
to
7b357ab
Compare
Hi @aduth and @jasmussen thank you for your feedback. I end up adding the CSS rule referred by @jasmussen, I think it improves the design compared to what we had, thank you @jasmussen 👍 I think the rule may be fragile e.g: if panel title was a div it would not work, but right now it seems like our best bet and it solves the problem. Maybe the panel body should have title and content in separate dom containers and the :first-child selector could be used for rows, it is something to check and discuss after, but from the design point of view as things are right now the result would be the same. |
7b357ab
to
88cdbf5
Compare
Test cases were updated, the addition of the wrapper to allow keys to be set in the right place made the props test case even less intuitive, that test case was removed and another test case that tests the rendering of multiple taxonomies was added. I think this made tests cases simpler to understand and still relevant. |
Hi @karmatosed, can you please have a final look regarding the user experience perspective? |
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.
Code-wise, looks good 👍
components/panel/style.scss
Outdated
@@ -134,6 +134,10 @@ | |||
&:empty { | |||
margin-top: 0; | |||
} | |||
|
|||
&:first-of-type { | |||
margin-top: 0px; |
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.
Minor: 0
doesn't need a unit. Further, this could be merged into the selector above:
&:empty,
&:first-of-type {
margin-top: 0;
}
495fb69
to
53d2dd9
Compare
Before all taxonomies appeared under "Categories & Tags" panel.
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.
Looks good to me, thanks for iterating on this.
53d2dd9
to
3e86770
Compare
This PR promotes each taxonomy to be a top-level panel (equal to the classic editor).
Closes: #4599
How Has This Been Tested?
Open post editor, verify now we don't have panel named "Categories & Tags" but a panel for categories and another one for tabs. Open and close the panels and verify things work as expected.
Change the categories & tags and check the functionality was not affected.
Add a custom taxonomy e.g: Type of Project, verify the taxonomy is rendered with the correct labels and works as expected.
Screenshots (jpeg or gifs if applicable):