Skip to content
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

State: Migrate lib/site-roles to Redux state #9249

Merged
merged 6 commits into from
Nov 14, 2016
Merged

Conversation

tyxla
Copy link
Member

@tyxla tyxla commented Nov 9, 2016

This PR migrates from the legacy lib/site-roles Flux store to Redux - fixes #7921. The PR takes care of the following:

  • Creates Redux actions, reducer, schema, selectors and README for site roles.
  • Adds tests for the above.
  • Introduces a QuerySiteRoles query component.
  • Updates the RoleSelect component to use Redux and converts it to a stateless functional component.
  • Removes the legacy lib/site-roles Flux store.

To test:

  1. Checkout this branch.
  2. Use one of your public WordPress.com sites for the next steps.
  3. Go to People, click on a user and verify the roles load properly in the Role field.
  4. Click on the button to add a new user and verify the roles load properly in the Role field.
  5. Verify step 3 and 4 work properly with a clean Redux state.
  6. Verify the last role in the role select field is called Follower.
  7. Use one of your private WordPress.com sites, go through steps 3 to 6, but this time verify the last role is called "Viewer".
  8. Use one of your Jetpack sites and go through step 3 to 5, verify all works as expected.
  9. Verify all tests pass: npm run test-client client/state/site-roles/

@matticbot
Copy link
Contributor

@tyxla tyxla force-pushed the update/redixify-site-roles branch 2 times, most recently from 037c50a to 793ebe4 Compare November 10, 2016 08:22
@tyxla tyxla added [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. and removed [Status] In Progress labels Nov 10, 2016
@tyxla
Copy link
Member Author

tyxla commented Nov 10, 2016

/cc @aduth @ockham

@@ -118,7 +118,7 @@ UndocumentedSite.prototype.shortcodes = function( attributes, callback ) {
};

UndocumentedSite.prototype.getRoles = function( callback ) {
this.wpcom.withLocale().req.get( '/sites/' + this._id + '/roles', {}, callback );
return this.wpcom.withLocale().req.get( '/sites/' + this._id + '/roles', {}, callback );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you rebase, this change will be omitted now (#9116), though merge will figure it out too in any case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 true - I rebased, and it did go away. Great job with #9116 btw.


const RoleSelect = ( props ) => {
const { siteRoles, site, includeFollower, siteId, id, explanation, translate } = props;
const roles = siteRoles && siteRoles.slice( 0 );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of Array#slice to copy the array because we use Array#push below, we could instead use Array#concat:

let { siteRoles } = props;
if ( siteRoles && includeFollower ) {
    siteRoles = siteRoles.concat( getWPCOMFollowerRole( props ) );
}

import { getSite } from 'state/sites/selectors';
import { getSiteRoles } from 'state/site-roles/selectors';

const getWPCOMFollowerRole = ( { site, translate } ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per naming conventions on abbreviations this should probably be getWpcomFollowerRole

return;
return (
<FormFieldset key={ siteId } disabled={ ! roles }>
{ siteId &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work the way you think it does. The logic is such that it'll check the truthiness of each and stop at whichever is falsey or the final value, so it'd either render null for an empty site ID or the <QuerySiteRoles /> component, but never the <QuerySites /> component.

Instead, you might want:

{ siteId && <QuerySites siteId={ siteId } /> }
{ siteId && <QuerySiteRoles siteId={ siteId } /> }

Or:

{ siteId && [
    <QuerySites key="query-sites" siteId={ siteId } />,
    <QuerySiteRoles key="query-site-roles" siteId={ siteId } />
] }

</FormSettingExplanation>
<FormLabel htmlFor={ id }>
{ translate( 'Role', {
context: 'Text that is displayed in a label of a form.'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledging it was there previously, I find this to be a strange context for the string. Why do we need context in this case? Role doesn't seem specific to a form.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense - I don't think this would help the translators in any way, so removing that.

</FormLabel>
<FormSelect { ...omit( props, omitProps ) }>
{
roles && roles.map( ( role ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nice thing about Lodash's map is that it would handle the empty roles for you automatically.

It's also generally faster.

I don't feel particularly strongly about changing this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I was left with the impression that the native Array.map would be faster. Good call, thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With latest changes, you don't need the siteRoles && check anymore. map will return an empty array if passed a falsey value.

Oh, I was left with the impression that the native Array.map would be faster.

Lodash "cheats" and sometimes forgoes full spec compliancy vs. native counterparts in favor of performance. In the case of array iteration ignoring sparse array checks.

See also:

dispatch( {
type: SITE_ROLES_REQUEST_FAILURE,
siteId,
error: pick( error, [ 'error', 'status', 'message' ] )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a lot of work to shape an object that we don't use 😄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Removing this, since we don't use the error at all.

@tyxla tyxla force-pushed the update/redixify-site-roles branch from 793ebe4 to 09c8fd5 Compare November 11, 2016 15:36
@tyxla
Copy link
Member Author

tyxla commented Nov 11, 2016

Thanks for the review, @aduth, the PR is ready for a new one.

Copy link
Contributor

@aduth aduth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works well in my testing. A few thoughts that may or may not make sense to address here vs. a subsequent pull request, but otherwise LGTM 👍

];

if ( site && siteRoles && includeFollower ) {
siteRoles = siteRoles.concat( getWpcomFollowerRole( props ) );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think this is something that belongs in a state selector? In other words, should getSiteRoles include the follower role automatically when the site is not private?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that would make sense. I didn't want to overcomplicate this PR, so let's keep this for another one.

<FormLabel htmlFor={ id }>
{ translate( 'Role' ) }
</FormLabel>
<FormSelect { ...omit( props, omitProps ) }>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we could figure out based on usage what's expected for this component to pass through (e.g. onChange), would be nice to avoid the omit. I see in a few cases there's an id and name passed, though I'm doubtful those are really necessary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. The list of omitProps has grown. Let's keep this for another PR.

@aduth aduth added [Status] Ready to Merge and removed [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Nov 11, 2016
@tyxla tyxla force-pushed the update/redixify-site-roles branch from d331391 to 5e32301 Compare November 14, 2016 07:36
@tyxla tyxla merged commit 324337f into master Nov 14, 2016
@tyxla tyxla deleted the update/redixify-site-roles branch November 14, 2016 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

State: Migrate lib/site-roles to Redux state
3 participants