From 8c2a105fad22e885d0600612257b47b08e619fb6 Mon Sep 17 00:00:00 2001 From: Igor Zinovyev Date: Fri, 27 Jan 2017 16:46:34 +0300 Subject: [PATCH 1/5] Added a proof of concept banner to the Antispam settings. --- _inc/client/security/antispam.jsx | 34 ++++++++++++++++++++++++++++++- _inc/client/security/index.jsx | 2 +- webpack.config.js | 4 ++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/_inc/client/security/antispam.jsx b/_inc/client/security/antispam.jsx index d46e0f2e75519..98b6958ab8edf 100644 --- a/_inc/client/security/antispam.jsx +++ b/_inc/client/security/antispam.jsx @@ -2,18 +2,29 @@ * External dependencies */ import React from 'react'; +import { connect } from 'react-redux'; import { translate as __ } from 'i18n-calypso'; /** * Internal dependencies */ +import Banner from 'components/banner'; +import { + FEATURE_SPAM_AKISMET_PLUS, + PLAN_JETPACK_PREMIUM, + getPlanClass +} from 'lib/plans/constants'; import { FormFieldset } from 'components/forms'; import { ModuleSettingsForm as moduleSettingsForm } from 'components/module-settings/module-settings-form'; import { ModuleSettingCheckbox } from 'components/module-settings/form-components'; import SettingsCard from 'components/settings-card'; import SettingsGroup from 'components/settings-group'; +import { + getSitePlan, + isFetchingSiteData +} from 'state/site'; -export const Antispam = moduleSettingsForm( +const Antispam = moduleSettingsForm( React.createClass( { toggleModule( name, value ) { @@ -21,6 +32,17 @@ export const Antispam = moduleSettingsForm( }, render() { + let planClass = getPlanClass( this.props.sitePlan.product_slug ); + + let banner = ( + + ); return ( + { 'is-free-plan' === planClass && banner } ); } } ) ); + +export default connect( + ( state ) => { + return { + sitePlan: getSitePlan( state ), + fetchingSiteData: isFetchingSiteData( state ) + }; + } +)( Antispam ); diff --git a/_inc/client/security/index.jsx b/_inc/client/security/index.jsx index d659fb5e96e39..4cf68ea7b274a 100644 --- a/_inc/client/security/index.jsx +++ b/_inc/client/security/index.jsx @@ -13,7 +13,7 @@ import { isDevMode, isUnavailableInDevMode } from 'state/connection'; import { isModuleFound as _isModuleFound } from 'state/search'; import QuerySite from 'components/data/query-site'; import { BackupsScan } from './backups-scan'; -import { Antispam } from './antispam'; +import Antispam from './antispam'; import { Protect } from './protect'; import { SSO } from './sso'; diff --git a/webpack.config.js b/webpack.config.js index a69bdc629231d..e1f2cdd4ef5d7 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -60,6 +60,10 @@ var webpackConfig = { { test: /\.scss$/, loader: ExtractTextPlugin.extract( 'style-loader', 'css!sass' ) + }, + { + test: /\.svg/, + loader: 'url-loader' } ] }, From 4e7394398e0bd651c196089445a30cad8fc91f1c Mon Sep 17 00:00:00 2001 From: Igor Zinovyev Date: Thu, 2 Feb 2017 23:30:55 +0300 Subject: [PATCH 2/5] Added banners with initial copy. --- .../client/components/settings-card/index.jsx | 121 +++++++++++++++++- _inc/client/security/antispam.jsx | 34 +---- _inc/client/security/backups-scan.jsx | 2 + _inc/client/security/index.jsx | 2 +- _inc/client/traffic/seo.jsx | 2 + _inc/client/writing/media.jsx | 7 +- 6 files changed, 131 insertions(+), 37 deletions(-) diff --git a/_inc/client/components/settings-card/index.jsx b/_inc/client/components/settings-card/index.jsx index 8a1b276fe431e..9821bc4e5be21 100644 --- a/_inc/client/components/settings-card/index.jsx +++ b/_inc/client/components/settings-card/index.jsx @@ -2,12 +2,30 @@ * External dependencies */ import React from 'react'; +import { connect } from 'react-redux'; import { translate as __ } from 'i18n-calypso'; /** * Internal dependencies */ +import { + PLAN_JETPACK_PREMIUM, + PLAN_JETPACK_BUSINESS, + FEATURE_GOOGLE_ANALYTICS_JETPACK, + FEATURE_SECURITY_SCANNING_JETPACK, + FEATURE_SEO_TOOLS_JETPACK, + FEATURE_SITE_BACKUPS_JETPACK, + FEATURE_SPAM_AKISMET_PLUS, + FEATURE_VIDEO_HOSTING_JETPACK, + FEATURE_WORDADS_JETPACK, + getPlanClass +} from 'lib/plans/constants'; +import { + getSitePlan, + isFetchingSiteData +} from 'state/site'; import SectionHeader from 'components/section-header'; +import Banner from 'components/banner'; import Button from 'components/button'; const SettingsCard = props => { @@ -17,12 +35,103 @@ const SettingsCard = props => { header = props.header ? props.header : '', - isSaving = props.isSavingAnyOption(); + isSaving = props.isSavingAnyOption(), + feature = props.feature + ? props.feature + : false; if ( '' === header && module ) { header = module.name; } + let getBanner = ( feature ) => { + let planClass = getPlanClass( props.sitePlan.product_slug ); + let list; + + switch( feature ) { + case FEATURE_VIDEO_HOSTING_JETPACK: + if ( + 'is-premium-plan' === planClass + || 'is-business-plan' === planClass + ) { + return ''; + } + + return ( + + ); + + case FEATURE_SECURITY_SCANNING_JETPACK: + if ( 'is-business-plan' === planClass ) { + return ''; + } + + list = [ + __( 'Automatic backups of every single aspect of your site' ), + __( 'Comprehensive and automated scanning for any security vulnerabilites or threats' ), + ]; + + if ( 'is-premium-plan' !== planClass ) { + list.unshift( + __( 'State-of-the-art spam defence powered by Akismet' ) + ); + } + + return ( + + ); + + case FEATURE_SEO_TOOLS_JETPACK: + if ( 'is-business-plan' === planClass ) { + return ''; + } + + list = [ + __( 'SEO tools to optimize your site for search engines and social media sharing' ), + __( 'Google Analytics tracking settings to complement WordPress.com stats' ), + ]; + + if ( 'is-premium-plan' !== planClass ) { + list.unshift( + __( 'Enable advertisements on your site to earn money from impressions' ) + ); + } + + return ( + + ); + + default: + return ''; + } + }; + return (
@@ -44,8 +153,16 @@ const SettingsCard = props => { } { props.children } + { getBanner( feature ) }
); }; -export default SettingsCard; +export default connect( + ( state ) => { + return { + sitePlan: getSitePlan( state ), + fetchingSiteData: isFetchingSiteData( state ) + }; + } +)( SettingsCard ); diff --git a/_inc/client/security/antispam.jsx b/_inc/client/security/antispam.jsx index 98b6958ab8edf..d46e0f2e75519 100644 --- a/_inc/client/security/antispam.jsx +++ b/_inc/client/security/antispam.jsx @@ -2,29 +2,18 @@ * External dependencies */ import React from 'react'; -import { connect } from 'react-redux'; import { translate as __ } from 'i18n-calypso'; /** * Internal dependencies */ -import Banner from 'components/banner'; -import { - FEATURE_SPAM_AKISMET_PLUS, - PLAN_JETPACK_PREMIUM, - getPlanClass -} from 'lib/plans/constants'; import { FormFieldset } from 'components/forms'; import { ModuleSettingsForm as moduleSettingsForm } from 'components/module-settings/module-settings-form'; import { ModuleSettingCheckbox } from 'components/module-settings/form-components'; import SettingsCard from 'components/settings-card'; import SettingsGroup from 'components/settings-group'; -import { - getSitePlan, - isFetchingSiteData -} from 'state/site'; -const Antispam = moduleSettingsForm( +export const Antispam = moduleSettingsForm( React.createClass( { toggleModule( name, value ) { @@ -32,17 +21,6 @@ const Antispam = moduleSettingsForm( }, render() { - let planClass = getPlanClass( this.props.sitePlan.product_slug ); - - let banner = ( - - ); return ( - { 'is-free-plan' === planClass && banner } ); } } ) ); - -export default connect( - ( state ) => { - return { - sitePlan: getSitePlan( state ), - fetchingSiteData: isFetchingSiteData( state ) - }; - } -)( Antispam ); diff --git a/_inc/client/security/backups-scan.jsx b/_inc/client/security/backups-scan.jsx index e5cca3dfb3e12..25776bdc38d62 100644 --- a/_inc/client/security/backups-scan.jsx +++ b/_inc/client/security/backups-scan.jsx @@ -7,6 +7,7 @@ import { translate as __ } from 'i18n-calypso'; /** * Internal dependencies */ +import { FEATURE_SECURITY_SCANNING_JETPACK } from 'lib/plans/constants'; import ExternalLink from 'components/external-link'; import { ModuleSettingsForm as moduleSettingsForm } from 'components/module-settings/module-settings-form'; import SettingsCard from 'components/settings-card'; @@ -22,6 +23,7 @@ export const BackupsScan = moduleSettingsForm( render() { return ( diff --git a/_inc/client/security/index.jsx b/_inc/client/security/index.jsx index 4cf68ea7b274a..d659fb5e96e39 100644 --- a/_inc/client/security/index.jsx +++ b/_inc/client/security/index.jsx @@ -13,7 +13,7 @@ import { isDevMode, isUnavailableInDevMode } from 'state/connection'; import { isModuleFound as _isModuleFound } from 'state/search'; import QuerySite from 'components/data/query-site'; import { BackupsScan } from './backups-scan'; -import Antispam from './antispam'; +import { Antispam } from './antispam'; import { Protect } from './protect'; import { SSO } from './sso'; diff --git a/_inc/client/traffic/seo.jsx b/_inc/client/traffic/seo.jsx index fca20a58206e6..ebf2fbf5f3126 100644 --- a/_inc/client/traffic/seo.jsx +++ b/_inc/client/traffic/seo.jsx @@ -8,6 +8,7 @@ import ExternalLink from 'components/external-link'; /** * Internal dependencies */ +import { FEATURE_SEO_TOOLS_JETPACK } from 'lib/plans/constants'; import { ModuleSettingsForm as moduleSettingsForm } from 'components/module-settings/module-settings-form'; import SettingsCard from 'components/settings-card'; import SettingsGroup from 'components/settings-group'; @@ -20,6 +21,7 @@ export const SEO = moduleSettingsForm(

diff --git a/_inc/client/writing/media.jsx b/_inc/client/writing/media.jsx index 5a334179adf9e..ea802eaf619ef 100644 --- a/_inc/client/writing/media.jsx +++ b/_inc/client/writing/media.jsx @@ -9,6 +9,7 @@ import CompactFormToggle from 'components/form/form-toggle/compact'; /** * Internal dependencies */ +import { FEATURE_VIDEO_HOSTING_JETPACK } from 'lib/plans/constants'; import { FormFieldset, FormLegend, @@ -77,7 +78,11 @@ const Media = moduleSettingsForm( isCarouselActive = this.props.getOptionValue( 'carousel' ); let photonSettings = ( - + Date: Thu, 2 Feb 2017 23:59:02 +0300 Subject: [PATCH 3/5] Added a link to the plans comparison page. --- .../client/components/settings-card/index.jsx | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/_inc/client/components/settings-card/index.jsx b/_inc/client/components/settings-card/index.jsx index 9821bc4e5be21..488c42b8a685d 100644 --- a/_inc/client/components/settings-card/index.jsx +++ b/_inc/client/components/settings-card/index.jsx @@ -20,6 +20,7 @@ import { FEATURE_WORDADS_JETPACK, getPlanClass } from 'lib/plans/constants'; +import { getSiteRawUrl } from 'state/initial-state'; import { getSitePlan, isFetchingSiteData @@ -38,7 +39,8 @@ const SettingsCard = props => { isSaving = props.isSavingAnyOption(), feature = props.feature ? props.feature - : false; + : false, + siteRawUrl = props.siteRawUrl; if ( '' === header && module ) { header = module.name; @@ -47,6 +49,10 @@ const SettingsCard = props => { let getBanner = ( feature ) => { let planClass = getPlanClass( props.sitePlan.product_slug ); let list; + let commonProps = { + feature: feature, + href: 'https://jetpack.com/redirect/?source=plans-compare-personal&site=' + siteRawUrl + }; switch( feature ) { case FEATURE_VIDEO_HOSTING_JETPACK: @@ -59,11 +65,10 @@ const SettingsCard = props => { return ( ); @@ -85,15 +90,14 @@ const SettingsCard = props => { return ( ); @@ -115,15 +119,14 @@ const SettingsCard = props => { return ( ); @@ -145,8 +148,8 @@ const SettingsCard = props => { disabled={ isSaving || ! props.isDirty() }> { isSaving - ? __( 'Saving…', { context: 'Button caption' } ) - : __( 'Save settings', { context: 'Button caption' } ) + ? __( 'Saving…', { context: 'Button caption' } ) + : __( 'Save settings', { context: 'Button caption' } ) } ) @@ -162,7 +165,8 @@ export default connect( ( state ) => { return { sitePlan: getSitePlan( state ), - fetchingSiteData: isFetchingSiteData( state ) + fetchingSiteData: isFetchingSiteData( state ), + siteRawUrl: getSiteRawUrl( state ), }; } )( SettingsCard ); From cc2c2b37a087dee488020ed980a858568e64d18a Mon Sep 17 00:00:00 2001 From: Igor Zinovyev Date: Fri, 17 Feb 2017 12:46:10 +0300 Subject: [PATCH 4/5] Fixed the VideoPress banner and some lint errors. --- _inc/client/components/settings-card/index.jsx | 8 ++------ _inc/client/writing/media.jsx | 6 +++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/_inc/client/components/settings-card/index.jsx b/_inc/client/components/settings-card/index.jsx index 488c42b8a685d..9578ffe06729c 100644 --- a/_inc/client/components/settings-card/index.jsx +++ b/_inc/client/components/settings-card/index.jsx @@ -11,13 +11,9 @@ import { translate as __ } from 'i18n-calypso'; import { PLAN_JETPACK_PREMIUM, PLAN_JETPACK_BUSINESS, - FEATURE_GOOGLE_ANALYTICS_JETPACK, FEATURE_SECURITY_SCANNING_JETPACK, FEATURE_SEO_TOOLS_JETPACK, - FEATURE_SITE_BACKUPS_JETPACK, - FEATURE_SPAM_AKISMET_PLUS, FEATURE_VIDEO_HOSTING_JETPACK, - FEATURE_WORDADS_JETPACK, getPlanClass } from 'lib/plans/constants'; import { getSiteRawUrl } from 'state/initial-state'; @@ -96,7 +92,7 @@ const SettingsCard = props => { 'is-premium-plan' !== planClass ? PLAN_JETPACK_PREMIUM : PLAN_JETPACK_BUSINESS - } + } { ...commonProps } /> ); @@ -125,7 +121,7 @@ const SettingsCard = props => { 'is-premium-plan' !== planClass ? PLAN_JETPACK_PREMIUM : PLAN_JETPACK_BUSINESS - } + } { ...commonProps } /> ); diff --git a/_inc/client/writing/media.jsx b/_inc/client/writing/media.jsx index ea802eaf619ef..70189b14187b8 100644 --- a/_inc/client/writing/media.jsx +++ b/_inc/client/writing/media.jsx @@ -81,8 +81,7 @@ const Media = moduleSettingsForm( + module={ photon }> + header={ __( 'Media' ) } + feature={ FEATURE_VIDEO_HOSTING_JETPACK }> { this.props.isModuleFound( 'photon' ) && photonSettings } { this.props.isModuleFound( 'carousel' ) && carouselSettings } From 169fcbd87290dce6e37a5a4b8a6b1d02d0acc8d9 Mon Sep 17 00:00:00 2001 From: Elio Rivero Date: Fri, 17 Feb 2017 11:39:01 -0300 Subject: [PATCH 5/5] GUI Tests: fix tests for SettingsCard component --- _inc/client/components/settings-card/index.jsx | 2 +- _inc/client/components/settings-card/test/component.js | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/_inc/client/components/settings-card/index.jsx b/_inc/client/components/settings-card/index.jsx index 9578ffe06729c..547a39bf1edd9 100644 --- a/_inc/client/components/settings-card/index.jsx +++ b/_inc/client/components/settings-card/index.jsx @@ -25,7 +25,7 @@ import SectionHeader from 'components/section-header'; import Banner from 'components/banner'; import Button from 'components/button'; -const SettingsCard = props => { +export const SettingsCard = props => { let module = props.module ? props.getModule( props.module ) : false, diff --git a/_inc/client/components/settings-card/test/component.js b/_inc/client/components/settings-card/test/component.js index 0ab7d9a4a984d..c171437f9694b 100644 --- a/_inc/client/components/settings-card/test/component.js +++ b/_inc/client/components/settings-card/test/component.js @@ -9,7 +9,7 @@ import sinon from 'sinon'; /** * Internal dependencies */ -import SettingsCard from '../index'; +import { SettingsCard } from '../index'; describe( 'SettingsCard', () => { @@ -25,7 +25,10 @@ describe( 'SettingsCard', () => { isSavingAnyOption: () => false, isDirty: () => true, header: '', - support: '' + support: '', + sitePlan: { + product_slug: 'jetpack_free' + } }; const wrapper = shallow( );