diff --git a/client/blocks/checklist/checklist-task.jsx b/client/components/checklist/task.js
similarity index 60%
rename from client/blocks/checklist/checklist-task.jsx
rename to client/components/checklist/task.js
index 9517f6dd78405..58f6db74d7f49 100644
--- a/client/blocks/checklist/checklist-task.jsx
+++ b/client/components/checklist/task.js
@@ -1,68 +1,56 @@
+/** @format */
/**
* External dependencies
- *
- * @format
*/
-
-import React, { PureComponent } from 'react';
-import PropTypes from 'prop-types';
-import { localize } from 'i18n-calypso';
-import { noop } from 'lodash';
import classNames from 'classnames';
import Gridicon from 'gridicons';
+import PropTypes from 'prop-types';
+import React, { PureComponent } from 'react';
+import { localize } from 'i18n-calypso';
/**
* Internal dependencies
*/
import Button from 'components/button';
-import Card from 'components/card';
+import CompactCard from 'components/card/compact';
import Focusable from 'components/focusable';
import ScreenReaderText from 'components/screen-reader-text';
-export class ChecklistTask extends PureComponent {
+export class Task extends PureComponent {
static propTypes = {
- id: PropTypes.string.isRequired,
- title: PropTypes.string.isRequired,
- buttonText: PropTypes.string,
- buttonPrimary: PropTypes.bool,
- completedTitle: PropTypes.string,
- completedButtonText: PropTypes.string,
- description: PropTypes.string.isRequired,
- duration: PropTypes.string,
completed: PropTypes.bool,
- onAction: PropTypes.func,
- onToggle: PropTypes.func,
- };
+ onClick: PropTypes.func,
+ onDismiss: PropTypes.func,
- static defaultProps = {
- onClick: noop,
- };
-
- handleClick = () => {
- this.props.onAction( this.props.id );
- };
-
- handleToggle = () => {
- this.props.onToggle( this.props.id );
+ buttonPrimary: PropTypes.bool,
+ completedButtonText: PropTypes.node,
+ completedTitle: PropTypes.node,
+ description: PropTypes.node,
+ duration: PropTypes.string,
+ title: PropTypes.node.isRequired,
+ translate: PropTypes.func.isRequired,
};
render() {
const {
buttonPrimary,
completed,
- completedTitle,
completedButtonText,
+ completedTitle,
description,
duration,
+ onClick,
+ onDismiss,
title,
translate,
} = this.props;
const { buttonText = translate( 'Do it!' ) } = this.props;
const hasActionlink = completed && completedButtonText;
+ const ToggleContainer = onDismiss ? Focusable : 'div';
+
return (
-
-
@@ -82,11 +70,7 @@ export class ChecklistTask extends PureComponent {
) }
-
+
{ hasActionlink ? completedButtonText : buttonText }
{ duration && (
@@ -95,19 +79,31 @@ export class ChecklistTask extends PureComponent {
) }
-
- { completed ? translate( 'Mark as uncompleted' ) : translate( 'Mark as completed' ) }
+ { /* eslint-disable no-nested-ternary */
+ onDismiss
+ ? completed
+ ? translate( 'Mark as uncompleted' )
+ : translate( 'Mark as completed' )
+ : completed
+ ? translate( 'Complete' )
+ : translate( 'Not complete' )
+ /* eslint-enable no-nested-ternary */
+ }
- { }
-
-
+
+
+
);
}
}
-export default localize( ChecklistTask );
+export default localize( Task );
diff --git a/client/devdocs/design/blocks.jsx b/client/devdocs/design/blocks.jsx
index 2ab0242e3149f..b18fb93408fd2 100644
--- a/client/devdocs/design/blocks.jsx
+++ b/client/devdocs/design/blocks.jsx
@@ -26,7 +26,6 @@ import AllSites from 'blocks/all-sites/docs/example';
import CreditCardForm from 'blocks/credit-card-form/docs/example';
import CalendarButton from 'blocks/calendar-button/docs/example';
import CalendarPopover from 'blocks/calendar-popover/docs/example';
-import Checklist from 'blocks/checklist/docs/example';
import AuthorSelector from 'blocks/author-selector/docs/example';
import CommentButtons from 'blocks/comment-button/docs/example';
import DisconnectJetpackDialog from 'blocks/disconnect-jetpack/docs/example';
@@ -135,7 +134,6 @@ export default class AppComponents extends React.Component {
-
diff --git a/client/devdocs/design/component-examples.js b/client/devdocs/design/component-examples.js
index e85faf8f192af..97dc7db3bf7b6 100644
--- a/client/devdocs/design/component-examples.js
+++ b/client/devdocs/design/component-examples.js
@@ -14,7 +14,7 @@ export Buttons from 'components/button/docs/example';
export Cards from 'components/card/docs/example';
export CardHeading from 'components/card-heading/docs/example';
export Chart from 'components/chart/docs/example';
-export Checklist from 'blocks/checklist/docs/example';
+export Checklist from 'components/checklist/docs/example';
export ClipboardButtonInput from 'components/clipboard-button-input/docs/example';
export ClipboardButtons from 'components/forms/clipboard-button/docs/example';
export Collection from 'devdocs/design/search-collection';
diff --git a/client/devdocs/design/index.jsx b/client/devdocs/design/index.jsx
index 7580000b2a701..867cc89a8e4eb 100644
--- a/client/devdocs/design/index.jsx
+++ b/client/devdocs/design/index.jsx
@@ -39,6 +39,7 @@ import Buttons from 'components/button/docs/example';
import CardHeading from 'components/card-heading/docs/example';
import Cards from 'components/card/docs/example';
import Chart from 'components/chart/docs/example';
+import Checklist from 'components/checklist/docs/example';
import ClipboardButtonInput from 'components/clipboard-button-input/docs/example';
import ClipboardButtons from 'components/forms/clipboard-button/docs/example';
import Collection from 'devdocs/design/search-collection';
@@ -183,6 +184,7 @@ class DesignAssets extends React.Component {
+
diff --git a/client/devdocs/design/playground-scope.js b/client/devdocs/design/playground-scope.js
index 60d955acbf137..f259c2fa87727 100644
--- a/client/devdocs/design/playground-scope.js
+++ b/client/devdocs/design/playground-scope.js
@@ -20,7 +20,8 @@ export ButtonGroup from 'components/button-group';
export Button from 'components/button';
export Card from 'components/card';
export CardHeading from 'components/card-heading';
-export Checklist from 'blocks/checklist';
+export Checklist from 'components/checklist';
+export ChecklistTask from 'components/checklist/task';
export ClipboardButtonInput from 'components/clipboard-button-input';
export ClipboardButton from 'components/forms/clipboard-button';
export Collection from 'devdocs/design/search-collection';
diff --git a/client/extensions/woocommerce/app/dashboard/setup/tasks.js b/client/extensions/woocommerce/app/dashboard/setup/tasks.js
index 5174d6105f2fa..0aa8f46716193 100644
--- a/client/extensions/woocommerce/app/dashboard/setup/tasks.js
+++ b/client/extensions/woocommerce/app/dashboard/setup/tasks.js
@@ -9,7 +9,6 @@ import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { localize } from 'i18n-calypso';
-import { find } from 'lodash';
import page from 'page';
/**
@@ -20,7 +19,8 @@ import {
getTriedCustomizerDuringInitialSetup,
getCheckedTaxSetup,
} from 'woocommerce/state/sites/setup-choices/selectors';
-import Checklist from 'blocks/checklist';
+import Checklist from 'components/checklist';
+import Task from 'components/checklist/task';
import { getTotalProducts, areProductsLoaded } from 'woocommerce/state/sites/products/selectors';
import { fetchProducts } from 'woocommerce/state/sites/products/actions';
import { fetchPaymentMethods } from 'woocommerce/state/sites/payment-methods/actions';
@@ -30,6 +30,7 @@ import { arePaymentsSetup } from 'woocommerce/state/ui/payments/methods/selector
import { getLink } from 'woocommerce/lib/nav-utils';
import { recordTrack } from 'woocommerce/lib/analytics';
import { areAnyShippingMethodsEnabled } from 'woocommerce/state/ui/shipping/zones/selectors';
+import { loadTrackingTool } from 'state/analytics/actions';
class SetupTasks extends Component {
static propTypes = {
@@ -49,6 +50,8 @@ class SetupTasks extends Component {
this.props.fetchProducts( site.ID, { page: 1 } );
}
}
+
+ this.props.loadTrackingTool( 'HotJar' );
};
componentWillReceiveProps = newProps => {
@@ -64,114 +67,113 @@ class SetupTasks extends Component {
}
};
- getSetupTasks = () => {
- const {
- site,
- triedCustomizer,
- hasProducts,
- paymentsAreSetUp,
- shippingIsSetUp,
- taxesAreSetUp,
- translate,
- } = this.props;
- const siteSlug = encodeURIComponent( '//' + site.slug );
- const customizerUrl = getLink(
- 'https://:site/wp-admin/customize.php?store-wpcom-nux=true&return=' + siteSlug,
- site
- );
-
- return [
- {
- id: 'add-product',
- title: translate( 'Add a product' ),
- buttonText: translate( 'Add a product' ),
- buttonPrimary: true,
- completedTitle: translate( 'You have added a product' ),
- completedButtonText: translate( 'View products' ),
- description: translate( 'Start by adding the first product to your\u00a0store.' ),
- duration: translate( '%d minute', '%d minutes', { count: 3, args: [ 3 ] } ),
- url: getLink( '/store/product/:site', site ),
- completed: hasProducts,
- },
- {
- id: 'set-up-shipping',
- title: translate( 'Review shipping' ),
- buttonText: translate( 'Review shipping' ),
- buttonPrimary: true,
- completedTitle: translate( 'Shipping is set up' ),
- completedButtonText: translate( 'View shipping' ),
- description: translate( "We've set up shipping based on your store location." ),
- duration: translate( '%d minute', '%d minutes', { count: 2, args: [ 2 ] } ),
- url: getLink( '/store/settings/shipping/:site', site ),
- completed: shippingIsSetUp,
- },
- {
- id: 'set-up-payments',
- title: translate( 'Review payments' ),
- buttonText: translate( 'Review payments' ),
- buttonPrimary: true,
- completedTitle: translate( 'Payments are set up' ),
- completedButtonText: translate( 'Review payments' ),
- description: translate( 'Choose how you would like your customers to pay you.' ),
- duration: translate( '%d minute', '%d minutes', { count: 2, args: [ 2 ] } ),
- url: getLink( '/store/settings/payments/:site', site ),
- completed: paymentsAreSetUp,
- },
- {
- id: 'set-up-taxes',
- title: translate( 'Review taxes' ),
- buttonText: translate( 'Review taxes' ),
- buttonPrimary: true,
- completedTitle: translate( 'Taxes are setup' ),
- completedButtonText: translate( 'Review taxes' ),
- description: translate( "We've set up automatic tax calculations for you." ),
- duration: translate( '%d minute', '%d minutes', { count: 2, args: [ 2 ] } ),
- url: getLink( '/store/settings/taxes/:site', site ),
- completed: taxesAreSetUp,
- },
- {
- id: 'view-and-customize',
- title: translate( 'View and customize' ),
- buttonText: translate( 'Customize' ),
- buttonPrimary: true,
- completedTitle: translate( 'View and customize' ),
- completedButtonText: translate( 'View and customize' ),
- description: translate(
- 'View your store and make any final tweaks before opening for business.'
- ),
- duration: translate( '%d minute', '%d minutes', { count: 4, args: [ 4 ] } ),
- url: customizerUrl,
- completed: triedCustomizer,
- },
- ];
- };
-
- handleAction = id => {
- const task = find( this.getSetupTasks(), { id } );
-
+ getClickHandler = ( id, url ) => () => {
recordTrack( 'calypso_woocommerce_dashboard_action_click', {
action: id,
} );
if ( 'view-and-customize' === id ) {
this.props.setTriedCustomizerDuringInitialSetup( this.props.site.ID, true );
- window.open( task.url );
+ window.open( url );
} else {
- page.show( task.url );
+ page.show( url );
}
};
render = () => {
+ const {
+ site,
+ triedCustomizer,
+ hasProducts,
+ paymentsAreSetUp,
+ shippingIsSetUp,
+ taxesAreSetUp,
+ translate,
+ } = this.props;
+ const siteSlug = encodeURIComponent( '//' + site.slug );
return (
+ isPlaceholder={ this.props.loading || ! this.props.productsLoaded }
+ inferCompletedCount
+ >
+
+
+
+
+
+
);
};
@@ -194,6 +196,7 @@ function mapDispatchToProps( dispatch ) {
{
fetchPaymentMethods,
fetchProducts,
+ loadTrackingTool,
setTriedCustomizerDuringInitialSetup,
},
dispatch
diff --git a/client/my-sites/checklist/checklist-show/index.jsx b/client/my-sites/checklist/checklist-show/index.jsx
index 5b07ac4d5d6ce..7472b4f5561be 100644
--- a/client/my-sites/checklist/checklist-show/index.jsx
+++ b/client/my-sites/checklist/checklist-show/index.jsx
@@ -11,7 +11,8 @@ import { find, get } from 'lodash';
/**
* Internal dependencies
*/
-import Checklist from 'blocks/checklist';
+import Checklist from 'components/checklist';
+import Task from 'components/checklist/task';
import { tasks as jetpackTasks } from '../jetpack-checklist';
import { requestSiteChecklistTaskUpdate } from 'state/checklist/actions';
import { getSelectedSiteId } from 'state/ui/selectors';
@@ -19,13 +20,16 @@ import getSiteChecklist from 'state/selectors/get-site-checklist';
import { isJetpackSite, getSiteSlug } from 'state/sites/selectors';
import QuerySiteChecklist from 'components/data/query-site-checklist';
import { launchTask, tasks as wpcomTasks } from '../onboardingChecklist';
-import { mergeObjectIntoArrayById } from '../util';
-import { recordTracksEvent } from 'state/analytics/actions';
+import { loadTrackingTool, recordTracksEvent } from 'state/analytics/actions';
import { createNotice } from 'state/notices/actions';
import { requestGuidedTour } from 'state/ui/guided-tours/actions';
class ChecklistShow extends PureComponent {
- handleAction = id => {
+ componentDidMount() {
+ this.props.loadTrackingTool( 'HotJar' );
+ }
+
+ handleAction = id => () => {
const { requestTour, siteSlug, tasks, track } = this.props;
const task = find( tasks, { id } );
@@ -38,7 +42,7 @@ class ChecklistShow extends PureComponent {
} );
};
- handleToggle = id => {
+ handleToggle = id => () => {
const { notify, siteId, tasks, update } = this.props;
const task = find( tasks, { id } );
@@ -49,17 +53,30 @@ class ChecklistShow extends PureComponent {
};
render() {
- const { siteId, tasks } = this.props;
+ const { isJetpack, siteId, taskStatuses } = this.props;
+ const tasks = isJetpack ? jetpackTasks : wpcomTasks;
return (
{ siteId && }
-
+
+ { tasks.map( task => (
+
+ ) ) }
+
);
}
@@ -67,20 +84,17 @@ class ChecklistShow extends PureComponent {
const mapStateToProps = state => {
const siteId = getSelectedSiteId( state );
- const siteSlug = getSiteSlug( state, siteId );
- const siteChecklist = getSiteChecklist( state, siteId );
- const isJetpack = isJetpackSite( state, siteId );
- const tasks = isJetpack ? jetpackTasks : wpcomTasks;
- const tasksFromServer = get( siteChecklist, [ 'tasks' ] );
return {
+ isJetpack: isJetpackSite( state, siteId ),
siteId,
- siteSlug,
- tasks: tasksFromServer ? mergeObjectIntoArrayById( tasks, tasksFromServer ) : null,
+ siteSlug: getSiteSlug( state, siteId ),
+ taskStatuses: get( getSiteChecklist( state, siteId ), [ 'tasks' ], null ),
};
};
const mapDispatchToProps = {
+ loadTrackingTool,
track: recordTracksEvent,
notify: createNotice,
requestTour: requestGuidedTour,