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

Focused Launch: PlanDetails View #47373

Merged
merged 10 commits into from
Nov 18, 2020
Merged

Conversation

tjcafferkey
Copy link
Contributor

@tjcafferkey tjcafferkey commented Nov 12, 2020

Changes proposed in this Pull Request

  • Implements the detailed plans step in Focused Launch

Testing instructions

  1. In the project root, run yarn && yarn start. In a separate terminal window, run cd apps/editing-toolkit && yarn dev --sync.
  2. Sandbox YOUR_SITE.wordpress.com.
  3. Visit https://YOUR_SITE.wordpress.com/wp-admin/post-new.php.
  4. In console, type wp.data.dispatch('automattic/launch' ).openFocusedLaunch().
  5. Click "View all plans".
  6. You should see the plans grid exactly as in the Figma file.

Fixes #46867

@matticbot
Copy link
Contributor

@tjcafferkey tjcafferkey added this to the Focused Launch: MVP milestone Nov 12, 2020
@alshakero alshakero force-pushed the update/focused-launch-all-plans-view branch from 74c1949 to f80a70a Compare November 16, 2020 13:53
@alshakero alshakero 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 16, 2020
@alshakero alshakero marked this pull request as ready for review November 16, 2020 13:53
@matticbot
Copy link
Contributor

matticbot commented Nov 16, 2020

Here is how your PR affects size of JS and CSS bundles shipped to the user's browser:

App Entrypoints (~480 bytes added 📈 [gzipped])

name                 parsed_size           gzip_size
entry-gutenboarding      +2437 B  (+0.1%)     +480 B  (+0.1%)

Common code that is always downloaded and parsed every time the app is loaded, no matter which route is used.

Sections (~122 bytes added 📈 [gzipped])

name             parsed_size           gzip_size
signup                +193 B  (+0.0%)      +43 B  (+0.0%)
jetpack-connect       +193 B  (+0.0%)      +36 B  (+0.0%)
accept-invite         +193 B  (+0.0%)      +43 B  (+0.0%)

Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to.

Async-loaded Components (~3899 bytes added 📈 [gzipped])

name                                           parsed_size            gzip_size
async-load-calypso-blocks-editor-launch-modal     +21117 B  (+12.2%)    +3899 B  (+8.6%)

React components that are loaded lazily, when a certain part of UI is displayed for the first time.

Legend

What is parsed and gzip size?

Parsed Size: Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory.
Gzip Size: Compressed size of the JS and CSS files. This much data needs to be downloaded over network.

Generated by performance advisor bot at iscalypsofastyet.com.

@tjcafferkey tjcafferkey requested a review from a team as a code owner November 16, 2020 18:04
@alshakero alshakero force-pushed the update/focused-launch-all-plans-view branch from d8d7248 to fc0a010 Compare November 16, 2020 18:05
@alshakero alshakero removed the request for review from a team November 16, 2020 18:05
showTaglines?: boolean;
CTAVariation?: 'FULL_WIDTH' | 'NORMAL';
popularBadgeVariation: 'ON_TOP' | 'NEXT_TO_NAME';
customTagLines?: Record< string, string >;

Choose a reason for hiding this comment

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

By looking at how this prop is used, we probably want keys to be typed as plan slugs.

}
}

.go-back-button__focused-launch:hover {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Non-blocker: Not a big deal just me being picky, but we could move this into the above selector to avoid repeating the selector.

.go-back-button__focused-launch {
	//...

	&:hover {
		opacity: 0.7;
	}
}


const { updatePlan } = useDispatch( LAUNCH_STORE );

const hasPaidDomain = domain && ! domain.is_free;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If domain is null or undefined you will get these values assigned to hasPaidDomain and it'll be coerced into a falsely value.

If you changed const hasPaidDomain = domain && ! domain.is_free; to const hasPaidDomain = domain?.is_free === false; then you'll get a more predictable boolean returned.

Not a blocker though, as it'll be coerced into a falsely value anyway.

Copy link
Member

Choose a reason for hiding this comment

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

Great idea but Typescript won't like because is_free is typed wrong.

@@ -34,6 +34,10 @@ export interface Props {
disabledPlans?: { [ planSlug: string ]: string };
isExperimental?: boolean;
locale: string;
showPlanTaglines?: boolean;
CTAVariation?: 'FULL_WIDTH' | 'NORMAL';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should export these values from the package similar to how domain picker has done here so we can use it like this

@@ -34,6 +34,10 @@ export interface Props {
disabledPlans?: { [ planSlug: string ]: string };
isExperimental?: boolean;
locale: string;
showPlanTaglines?: boolean;
CTAVariation?: 'FULL_WIDTH' | 'NORMAL';
popularBadgeVariation?: 'ON_TOP' | 'NEXT_TO_NAME';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should export these values from the package similar to how domain picker has done here so we can use it like this

@@ -23,6 +23,10 @@ export interface Props {
currentDomain?: DomainSuggestions.DomainSuggestion;
disabledPlans?: { [ planSlug: string ]: string };
locale: string;
showTaglines?: boolean;
CTAVariation?: 'FULL_WIDTH' | 'NORMAL';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should export these values from the package similar to how domain picker has done here so we can use it like this

@@ -48,6 +49,8 @@ export interface Props {
onToggleExpandAll?: () => void;
allPlansExpanded: boolean;
disabledLabel?: string;
CTAVariation: 'FULL_WIDTH' | 'NORMAL';
popularBadgeVariation: 'ON_TOP' | 'NEXT_TO_NAME';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should export these values from the package similar to how domain picker has done here so we can use it like this

>
<span>{ __( 'Choose', __i18n_text_domain__ ) }</span>
</Button>
{ CTAVariation === 'NORMAL' ? (
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we export the CTAVariation values, we can use them here instead of hard coding 'NORMAL'

Copy link
Member

Choose a reason for hiding this comment

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

I think exporting the type is enough. The IDE won't let you set an invalid value.

'badge-next-to-name': popularBadgeVariation === 'NEXT_TO_NAME',
} ) }
>
{ isPopular && popularBadgeVariation === 'ON_TOP' && (
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we export the popularBadgeVariation values, we can use them here instead of hard coding 'ON_TOP'

Copy link
Member

@alshakero alshakero Nov 18, 2020

Choose a reason for hiding this comment

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

Same as above.

<div className="plan-item__heading">
<div
className={ classNames( 'plan-item__heading', {
'badge-next-to-name': popularBadgeVariation === 'NEXT_TO_NAME',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we export the popularBadgeVariation values, we can use them here instead of hard coding 'NEXT_TO_NAME'

Copy link
Member

@alshakero alshakero Nov 18, 2020

Choose a reason for hiding this comment

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

Same as above.

<div className="plan-item__name">{ name }</div>
{ isPopular && popularBadgeVariation === 'NEXT_TO_NAME' && (
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we export the popularBadgeVariation values, we can use them here instead of hard coding 'NEXT_TO_NAME'

Copy link
Member

Choose a reason for hiding this comment

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

Same as above.

Comment on lines +54 to +57
CTAVariation = 'NORMAL',
popularBadgeVariation = 'ON_TOP',

Choose a reason for hiding this comment

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

I don't think we need to maintain another variation of the PlansGrid in a non-accordion mode. However, it's non blocking for this PR.

Just pinging @ollierozdarz to confirm so we can clean up later. Here is the old table version with badge on top and CTA non full-width.
Screenshot 2020-11-18 at 13 37 36

@tjcafferkey
Copy link
Contributor Author

Should we be able to "Deselect" a plan?

@razvanpapadopol
Copy link

razvanpapadopol commented Nov 18, 2020

Should we be able to "Deselect" a plan?

No, once we click Select on a plan, the modal is closed and we land back on the Summary View with that plan highlighted.
The behaviour should be similar to the one for DomainsDetails View described in #46866 (comment)


/**
* Internal dependencies
*/
import { Route } from '../route';
import { LAUNCH_STORE } from '../../stores';
import GoBackButton from '../go-back-button';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can we use Back Button from @automattic/onboarding? Seen here

Copy link

@razvanpapadopol razvanpapadopol Nov 18, 2020

Choose a reason for hiding this comment

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

An idea would be that GoBackButton should use BackButton and then reuse here and in DomainDetails View. See also #47497 (comment)

Copy link
Member

Choose a reason for hiding this comment

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

Great idea. Didn't know about this one.

@@ -3,22 +3,80 @@
/**
* External dependencies
*/
import React from 'react';
import { Link } from 'react-router-dom';
import * as React from 'react';
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of curiosity, what are the benefits of import * as React over import React ?

Copy link
Contributor Author

@tjcafferkey tjcafferkey Nov 18, 2020

Choose a reason for hiding this comment

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

I thought this. Looks like it's being used for the functional component typings but not sure the benefit of *

Copy link
Contributor

Choose a reason for hiding this comment

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

I thought it would work anyway

Choose a reason for hiding this comment

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

I know we used this way of importing for a while for performance reasons. I believe now we have webpack configured so this isn't necessary anymore. Pinging @sirreal to confirm though 🙏

Copy link
Member

Choose a reason for hiding this comment

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

If you do import React... you need allowSyntheticDefaultImports = true in tsconfig. import * as React is more semantically accurate and makes TypeScript happy. But don't quote me on this. I think (not sure) I saw @sirreal do it, and he is my TypeScript prophet.

Copy link
Member

Choose a reason for hiding this comment

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

There were some perf concerns and I don't know whether they're relevant. Either way, I think we have conclusive evidence that import * as React from 'react'; is "right": facebook/react#18102

[import * as React from "react";] is the correct way to import React from an ES module since the ES module will not have a default export. Only named exports.

I'm doing some changes to named exports and this will stop working. For open source ES modules we'll probably publish some default object that warns as an upgrade path but we can't use that in our own code.

We could add a lint rule for this and/or codemod it, but I don't know whether there is significant impact beyond consistency.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for the explanation! I learnt something new

Copy link
Member

Choose a reason for hiding this comment

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

If you do import React... you need allowSyntheticDefaultImports = true in tsconfig. import * as React is more semantically accurate and makes TypeScript happy.

Yes, I think this is right. Note, this isn't really about TypeScript but about ECMAScript modules which are quirky. I wrote a bit here (p4TIVU-8Lf-p2).

@alshakero
Copy link
Member

Addressed all. Thanks everyone!

@alshakero alshakero force-pushed the update/focused-launch-all-plans-view branch from 196aac6 to 02997af Compare November 18, 2020 14:34
@tjcafferkey
Copy link
Contributor Author

If you look at the linked issue which contains the designs and compare to the below screenshot the back button is missing some CSS lovin'

  • Font color
  • Margin bottom
  • Left chevron

Screenshot 2020-11-18 at 15 53 19

@ciampo are we sticking with the standard <BackButton /> styles or overwriting some so it's inline with the designs?

@ciampo
Copy link
Contributor

ciampo commented Nov 18, 2020

If you look at the linked issue which contains the designs and compare to the below screenshot the back button is missing some CSS lovin'

  • Font color
  • Margin bottom
  • Left chevron

Screenshot 2020-11-18 at 15 53 19

@ciampo are we sticking with the standard <BackButton /> styles or overwriting some so it's inline with the designs?

Good finds!

  • I'd say for sure that margin should be addressed because it doesn't really have to do with the component itself
  • For the left chevon, we should probably add it to the <BackButton /> and enable/disable it with a prop? Something like <BackButton showChevron={true} />
  • Regarding font color, I'm almost tempted to leave it as it is, as the overall color palette should ultimately come from the onboarding package

What do you think?

@tjcafferkey
Copy link
Contributor Author

@ciampo I think we can address the chevron issue by including the <Icon /> component as a child like so

<BackButton onClick={ goBack }>
	<Icon icon={ chevronLeft } />
	<span>{ __( 'Go back', __i18n_text_domain__ ) }</span>
</BackButton>

As for the margin, we should address this with a shared CSS class so it's consistent and leaving the color as it is I think makes sense as you said.

@tjcafferkey
Copy link
Contributor Author

@ciampo are we sticking with the standard styles or overwriting some so it's inline with the designs?

@alshakero we reached a conclusion on this here 27382-pb

Copy link
Contributor Author

@tjcafferkey tjcafferkey left a comment

Choose a reason for hiding this comment

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

I can't approve as it's my original PR but this LGTM!

@alshakero alshakero merged commit 254f872 into master Nov 18, 2020
@alshakero alshakero deleted the update/focused-launch-all-plans-view branch November 18, 2020 18:25
@matticbot matticbot removed the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Nov 18, 2020
Copy link
Collaborator

@wp-desktop wp-desktop left a comment

Choose a reason for hiding this comment

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

WordPress Desktop CI Failure for job "wp-desktop-mac".

@alshakero please inspect this job's build steps for breaking changes at this link. For temporal failures, you may try to "Rerun Workflow from Failed".

Please also ensure this branch is rebased off latest Calypso.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Focused Launch: detailed Plans Grid view
7 participants