Skip to content

Commit

Permalink
AT: Add/at plugins nudge (Automattic#13967)
Browse files Browse the repository at this point in the history
* removes the AT-enabled check before showing add plugin button

This also means we don't need redux connect, so I'm removing that too.

* display plugin UI to all users, but show upgrade nudge as appropriate

* use banner for both upgrade nudges

* hide plugins sidebar for users who cannot manage plugins

* show access error on plugin page for all sites, not just jetpack

* wpcom sites should not get a blank disallow message

* only show upgrade banner if user can manage plugins

* show access error for both wpcom and jetpack sites

* show page not available if user cannot manage plugins

* one-line formatting for compound conditional
  • Loading branch information
rralian authored May 12, 2017
1 parent 737a1f1 commit d207cb8
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 96 deletions.
50 changes: 19 additions & 31 deletions client/my-sites/plugins-wpcom/jetpack-plugins-panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* External dependencies
*/
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { localize } from 'i18n-calypso';
import {
find,
Expand Down Expand Up @@ -30,8 +29,6 @@ import NavItem from 'components/section-nav/item';
import Search from 'components/search';
import jetpackPlugins from './jetpack-plugins';
import Tooltip from 'components/tooltip';
import { isATEnabled } from 'lib/automated-transfer';
import { getSelectedSite } from 'state/ui/selectors';

const filterGroup = category => group => {
if ( category && category !== 'all' ) {
Expand Down Expand Up @@ -176,26 +173,24 @@ class JetpackPluginsPanel extends Component {
</SectionNav>

<SectionHeader label={ translate( 'Plugins' ) }>
{ this.props.atEnabled &&
<ButtonGroup key="plugin-list-header__buttons-browser">
<Button
compact
href={ browserUrl }
onMouseEnter={ this.showPluginTooltip }
onMouseLeave={ this.hidePluginTooltip }
ref="addPluginButton"
aria-label={ translate( 'Browse all plugins', { context: 'button label' } ) }>
<Gridicon key="plus-icon" icon="plus-small" size={ 18 } />
<Gridicon key="plugins-icon" icon="plugins" size={ 18 } />
<Tooltip
isVisible={ this.state.addPluginTooltip }
context={ this.refs && this.refs.addPluginButton }
position="bottom">
{ translate( 'Browse all plugins' ) }
</Tooltip>
</Button>
</ButtonGroup>
}
<ButtonGroup key="plugin-list-header__buttons-browser">
<Button
compact
href={ browserUrl }
onMouseEnter={ this.showPluginTooltip }
onMouseLeave={ this.hidePluginTooltip }
ref="addPluginButton"
aria-label={ translate( 'Browse all plugins', { context: 'button label' } ) }>
<Gridicon key="plus-icon" icon="plus-small" size={ 18 } />
<Gridicon key="plugins-icon" icon="plugins" size={ 18 } />
<Tooltip
isVisible={ this.state.addPluginTooltip }
context={ this.refs && this.refs.addPluginButton }
position="bottom">
{ translate( 'Browse all plugins' ) }
</Tooltip>
</Button>
</ButtonGroup>
</SectionHeader>

<CompactCard className="plugins-wpcom__jetpack-main-plugin plugins-wpcom__jetpack-plugin-item">
Expand Down Expand Up @@ -253,11 +248,4 @@ class JetpackPluginsPanel extends Component {
}
}

export default connect(
( state ) => {
const selectedSite = getSelectedSite( state );
return {
atEnabled: isATEnabled( selectedSite )
};
}
)( localize( urlSearch( JetpackPluginsPanel ) ) );
export default localize( urlSearch( JetpackPluginsPanel ) );
28 changes: 23 additions & 5 deletions client/my-sites/plugins-wpcom/plugin-panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
getSelectedSiteId
} from 'state/ui/selectors';
import { getSiteSlug } from 'state/sites/selectors';
import { canCurrentUser } from 'state/selectors';
import {
isPremium,
isBusiness,
Expand All @@ -23,27 +24,43 @@ import JetpackPluginsPanel from './jetpack-plugins-panel';
import PageViewTracker from 'lib/analytics/page-view-tracker';
import { PLAN_BUSINESS, FEATURE_UPLOAD_PLUGINS } from 'lib/plans/constants';
import Banner from 'components/banner';
import { isATEnabled } from 'lib/automated-transfer';
import MainComponent from 'components/main';
import EmptyContent from 'components/empty-content';

export const PluginPanel = ( {
plan,
siteSlug,
category,
search,
translate,
atEnabled
canUserManageOptions,
} ) => {
const hasBusiness = isBusiness( plan ) || isEnterprise( plan );
const hasPremium = hasBusiness || isPremium( plan );

if ( ! canUserManageOptions ) {
const accessError = {
title: translate( 'Not Available' ),
line: translate( 'The page you requested could not be found' ),
illustration: '/calypso/images/drake/drake-404.svg',
fullWidth: true
};
return (
<MainComponent>
<EmptyContent { ...accessError } />
</MainComponent>
);
}

return (
<div className="plugins-wpcom__panel">

<PageViewTracker path="/plugins/:site" title="Plugins > WPCOM Site" />

{ atEnabled && ! hasBusiness &&
{ ! hasBusiness &&
<Banner
feature={ FEATURE_UPLOAD_PLUGINS }
event={ 'calypso_plugins_page_upgrade_nudge' }
plan={ PLAN_BUSINESS }
title={ translate( 'Upgrade to the Business plan to install plugins.' ) }
/>
Expand All @@ -63,10 +80,11 @@ export const PluginPanel = ( {

const mapStateToProps = state => {
const selectedSite = getSelectedSite( state );
const selectedSiteId = getSelectedSiteId( state );
return {
atEnabled: isATEnabled( selectedSite ),
plan: get( selectedSite, 'plan', {} ),
siteSlug: getSiteSlug( state, getSelectedSiteId( state ) )
siteSlug: getSiteSlug( state, selectedSiteId ),
canUserManageOptions: canCurrentUser( state, selectedSiteId, 'manage_options' ),
};
};

Expand Down
12 changes: 0 additions & 12 deletions client/my-sites/plugins/access-control.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@ const hasErrorCondition = ( site, type ) => {
return errorConditions[ type ];
};

const getWpcomPluginPageError = () => {
return {
title: i18n.translate( 'Oops! Not supported' ),
line: i18n.translate( 'This site doesn\'t support installing plugins. Switch to a self-hosted site to install and manage plugins' ),
illustration: '/calypso/images/drake/drake-whoops.svg'
};
};

const hasRestrictedAccess = ( site ) => {
site = site || sites.getSelectedSite();

Expand All @@ -54,10 +46,6 @@ const hasRestrictedAccess = ( site ) => {
}
);
}

if ( ! sites.hasSiteWithPlugins() ) {
return getWpcomPluginPageError();
}
};

export default { hasRestrictedAccess };
10 changes: 5 additions & 5 deletions client/my-sites/plugins/plugin-meta/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import PluginInformation from 'my-sites/plugins/plugin-information';
import WpcomPluginInstallButton from 'my-sites/plugins-wpcom/plugin-install-button';
import PluginAutomatedTransfer from 'my-sites/plugins/plugin-automated-transfer';
import { userCan } from 'lib/site/utils';
import UpgradeNudge from 'my-sites/upgrade-nudge';
import { FEATURE_UPLOAD_PLUGINS } from 'lib/plans/constants';
import Banner from 'components/banner';
import { PLAN_BUSINESS, FEATURE_UPLOAD_PLUGINS } from 'lib/plans/constants';
import {
isBusiness,
isEnterprise
Expand Down Expand Up @@ -492,11 +492,11 @@ const PluginMeta = React.createClass( {

{ ! get( this.props.selectedSite, 'jetpack' ) && ! this.hasBusinessPlan() && ! this.isWpcomPreinstalled() &&
<div className="plugin-meta__upgrade_nudge">
<UpgradeNudge
<Banner
feature={ FEATURE_UPLOAD_PLUGINS }
event={ 'calypso_plugin_detail_page_upgrade_nudge' }
plan={ PLAN_BUSINESS }
title={ this.props.translate( 'Upgrade to the Business plan to install plugins.' ) }
message={ this.props.translate( 'Upgrade to the Business plan to install plugins.' ) }
event={ 'calypso_plugins_page_upgrade_nudge' }
/>
</div>
}
Expand Down
22 changes: 1 addition & 21 deletions client/my-sites/plugins/plugin.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@ import pluginsAccessControl from 'my-sites/plugins/access-control';
import EmptyContent from 'components/empty-content';
import FeatureExample from 'components/feature-example';
import DocumentHead from 'components/data/document-head';
import WpcomPluginsList from 'my-sites/plugins-wpcom/plugins-list';
import { getSelectedSite, getSelectedSiteId } from 'state/ui/selectors';
import { isJetpackSite, canJetpackSiteManage, getRawSite } from 'state/sites/selectors';
import { isSiteAutomatedTransfer } from 'state/selectors';
import { recordGoogleEvent } from 'state/analytics/actions';
import QuerySites from 'components/data/query-sites';
import { isATEnabled } from 'lib/automated-transfer';

const SinglePlugin = React.createClass( {
_DEFAULT_PLUGINS_BASE_PATH: 'http://wordpress.org/plugins/',
Expand Down Expand Up @@ -320,24 +318,7 @@ const SinglePlugin = React.createClass( {
render() {
const { selectedSite } = this.props;

if (
selectedSite &&
! this.props.isJetpackSite( selectedSite.ID ) &&
! this.props.atEnabled
) {
return (
<MainComponent>
{ this.renderDocumentHead() }
<SidebarNavigation />
<WpcomPluginsList />
</MainComponent>
);
}

if (
this.state.accessError &&
( ! selectedSite || selectedSite.jetpack )
) {
if ( this.state.accessError ) {
return (
<MainComponent>
{ this.renderDocumentHead() }
Expand Down Expand Up @@ -433,7 +414,6 @@ export default connect(
selectedSite: selectedSite,
isJetpackSite: siteId => isJetpackSite( state, siteId ),
canJetpackSiteManage: siteId => canJetpackSiteManage( state, siteId ),
atEnabled: isATEnabled( site ),
isSiteAutomatedTransfer: isSiteAutomatedTransfer( state, get( selectedSite, 'ID' ) ),
};
},
Expand Down
13 changes: 1 addition & 12 deletions client/my-sites/plugins/plugins-browser/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import { hasTouch } from 'lib/touch-detect';
import { recordTracksEvent } from 'state/analytics/actions';
import { getSelectedSite } from 'state/ui/selectors';
import { isJetpackSite, canJetpackSiteManage } from 'state/sites/selectors';
import { isATEnabled } from 'lib/automated-transfer';

const PluginsBrowser = React.createClass( {
_SHORT_LIST_LENGTH: 6,
Expand Down Expand Up @@ -318,16 +317,7 @@ const PluginsBrowser = React.createClass( {
! this.props.canJetpackSiteManage( selectedSite.ID )
);

if (
( this.state.accessError || cantManage ) &&
(
// If automated transfer is _off_ then behave
// as normal. If it's on, then only show if we
// are getting an error on a Jetpack site
! this.props.atEnabled ||
( selectedSite && selectedSite.jetpack )
)
) {
if ( ( this.state.accessError || cantManage ) && selectedSite ) {
return this.renderAccessError( selectedSite );
}

Expand All @@ -347,7 +337,6 @@ export default connect(
const selectedSite = getSelectedSite( state );
return {
selectedSite,
atEnabled: isATEnabled( selectedSite ),
isJetpackSite: siteId => isJetpackSite( state, siteId ),
canJetpackSiteManage: siteId => canJetpackSiteManage( state, siteId ),
};
Expand Down
18 changes: 8 additions & 10 deletions client/my-sites/sidebar/sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import {
isJetpackSite
} from 'state/sites/selectors';
import { getStatsPathForTab } from 'lib/route/path';
import { isATEnabled } from 'lib/automated-transfer';
import { abtest } from 'lib/abtest';

/**
Expand Down Expand Up @@ -203,13 +202,10 @@ export class MySitesSidebar extends Component {

plugins() {
const { site } = this.props;
const addPluginsLink = '/plugins/browse' + this.props.siteSuffix;
let pluginsLink = '/plugins' + this.props.siteSuffix;
let addPluginsLink;

if ( this.props.atEnabled ) {
addPluginsLink = '/plugins/browse' + this.props.siteSuffix;
}

// TODO: we can probably rip this out
if ( ! config.isEnabled( 'manage/plugins' ) ) {
if ( ! site ) {
return null;
Expand All @@ -220,12 +216,14 @@ export class MySitesSidebar extends Component {
}
}

// checks for manage plugins capability across all sites
if ( ! this.props.canManagePlugins ) {
return null;
}

if ( ( this.props.siteId && this.props.isJetpack ) || ( ! this.props.siteId && this.props.hasJetpackSites ) ) {
addPluginsLink = '/plugins/browse' + this.props.siteSuffix;
// if selectedSite and cannot manage, skip plugins section
if ( this.props.siteId && ! this.props.canUserManageOptions ) {
return null;
}

return (
Expand Down Expand Up @@ -257,7 +255,7 @@ export class MySitesSidebar extends Component {
return null;
}

if ( this.props.isJetpack && ! this.props.atEnabled ) {
if ( this.props.isJetpack && ! this.props.isSiteAutomatedTransfer ) {
return null;
}

Expand Down Expand Up @@ -594,13 +592,13 @@ function mapStateToProps( state ) {
const canManagePlugins = !! getSites( state ).some( ( s ) => (
( s.capabilities && s.capabilities.manage_options )
) );

// FIXME: Turn into dedicated selector
const hasJetpackSites = getSites( state ).some( s => s.jetpack );

const isPreviewShowing = getCurrentLayoutFocus( state ) === 'preview';

return {
atEnabled: isATEnabled( site ),
canManagePlugins,
canUserEditThemeOptions: canCurrentUser( state, siteId, 'edit_theme_options' ),
canUserListUsers: canCurrentUser( state, siteId, 'list_users' ),
Expand Down

0 comments on commit d207cb8

Please sign in to comment.