Skip to content

Commit 1ee5f52

Browse files
chickenn00dleclaude
andcommitted
feat(integrations): add inactive plugin state
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent fb6c06d commit 1ee5f52

5 files changed

Lines changed: 73 additions & 12 deletions

File tree

includes/reader-activation/class-integrations.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -424,13 +424,14 @@ public static function get_all_integration_settings() {
424424
continue;
425425
}
426426
$result[ $id ] = [
427-
'id' => $id,
428-
'name' => $integration->get_name(),
429-
'description' => $integration->get_description(),
430-
'enabled' => self::is_enabled( $id ),
431-
'is_set_up' => $integration->is_set_up(),
432-
'setup_url' => $integration->get_setup_url(),
433-
'settings' => $integration->get_settings_config(),
427+
'id' => $id,
428+
'name' => $integration->get_name(),
429+
'description' => $integration->get_description(),
430+
'enabled' => self::is_enabled( $id ),
431+
'is_set_up' => $integration->is_set_up(),
432+
'setup_url' => $integration->get_setup_url(),
433+
'settings' => $integration->get_settings_config(),
434+
'required_plugins' => $integration->get_required_plugins(),
434435
];
435436
}
436437
return $result;

includes/reader-activation/integrations/class-esp.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,23 @@ public function get_setup_url() {
6464
return $newsletters_configuration_manager->get_settings_url();
6565
}
6666

67+
/**
68+
* Get the plugins this integration depends on, with their install/active status.
69+
*
70+
* @return array List of associative arrays with keys `slug`, `name`, `is_active`, `is_installed`.
71+
*/
72+
public function get_required_plugins() {
73+
$status = \Newspack\Plugin_Manager::get_managed_plugin_status( 'newspack-newsletters' );
74+
return [
75+
[
76+
'slug' => 'newspack-newsletters',
77+
'name' => __( 'Newspack Newsletters', 'newspack-plugin' ),
78+
'is_active' => 'active' === $status,
79+
'is_installed' => 'uninstalled' !== $status,
80+
],
81+
];
82+
}
83+
6784
/**
6885
* Register the settings fields declared by this integration.
6986
*

includes/reader-activation/integrations/class-integration.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,19 @@ public function get_setup_url() {
151151
return '';
152152
}
153153

154+
/**
155+
* Get the plugins this integration depends on, with their active status.
156+
*
157+
* Child classes should override this to declare any plugins that must be
158+
* active for the integration to function. The integrations UI uses this
159+
* to surface a "requirements" affordance on the integration card.
160+
*
161+
* @return array List of associative arrays with keys `slug`, `name`, `is_active`.
162+
*/
163+
public function get_required_plugins() {
164+
return [];
165+
}
166+
154167
/**
155168
* Whether this integration supports frontend reader registration.
156169
*

src/wizards/audience/views/integrations/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,15 @@ const AudienceIntegrations = ( props, ref ) => {
8888
} );
8989
}, [] );
9090

91+
const handleActivatePlugin = useCallback(
92+
pluginSlug =>
93+
apiFetch( {
94+
path: `/newspack/v1/plugins/${ pluginSlug }/activate`,
95+
method: 'POST',
96+
} ).then( () => fetchSettings() ),
97+
[ fetchSettings ]
98+
);
99+
91100
const sharedProps = {
92101
integrations,
93102
pendingChanges,
@@ -97,6 +106,7 @@ const AudienceIntegrations = ( props, ref ) => {
97106
onFieldChange: handleFieldChange,
98107
onSave: handleSave,
99108
onToggleEnabled: handleToggleEnabled,
109+
onActivatePlugin: handleActivatePlugin,
100110
};
101111

102112
return (

src/wizards/audience/views/integrations/settings-section.js

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* WordPress dependencies
33
*/
4-
import { __ } from '@wordpress/i18n';
4+
import { __, sprintf } from '@wordpress/i18n';
55
import { Icon, envelope } from '@wordpress/icons';
66

77
/**
@@ -32,7 +32,9 @@ const DEFAULT_ICON = {
3232
backgroundColor: colors[ 'neutral-100' ],
3333
};
3434

35-
export const SettingsSection = ( { integrations, loading, onToggleEnabled, history } ) => {
35+
const getMissingPlugins = integration => ( integration.required_plugins || [] ).filter( plugin => ! plugin.is_active );
36+
37+
export const SettingsSection = ( { integrations, loading, onToggleEnabled, onActivatePlugin, history } ) => {
3638
const integrationIds = Object.keys( integrations );
3739

3840
return (
@@ -54,22 +56,40 @@ export const SettingsSection = ( { integrations, loading, onToggleEnabled, histo
5456
{ ! loading && integrationIds.length > 0 && (
5557
<Grid columns={ 2 } gutter={ 16 }>
5658
{ integrationIds.map( id => {
57-
const { enabled, is_set_up: isSetUp, setup_url, name, description } = integrations[ id ];
59+
const integration = integrations[ id ];
60+
const { enabled, is_set_up: isSetUp, setup_url, name, description } = integration;
61+
const missingPlugins = getMissingPlugins( integration );
62+
const uninstalledPlugin = missingPlugins.find( plugin => ! plugin.is_installed );
63+
const activatablePlugin = missingPlugins.length && ! uninstalledPlugin ? missingPlugins[ 0 ] : null;
64+
const requirements = uninstalledPlugin
65+
? sprintf(
66+
/* translators: %s: comma-separated list of required plugin names. */
67+
__( 'Requires %s', 'newspack-plugin' ),
68+
missingPlugins.map( plugin => plugin.name ).join( ', ' )
69+
)
70+
: undefined;
5871
const isEnabled = enabled;
5972
const needsSetup = ! isSetUp && !! setup_url;
6073
const goToSetup = () => {
6174
window.location.href = setup_url;
6275
};
76+
let enableLabel = isSetUp ? __( 'Enable', 'newspack-plugin' ) : __( 'Connect', 'newspack-plugin' );
77+
let onEnable = needsSetup ? goToSetup : () => onToggleEnabled( id, true );
78+
if ( activatablePlugin ) {
79+
enableLabel = __( 'Activate', 'newspack-plugin' );
80+
onEnable = () => onActivatePlugin( activatablePlugin.slug );
81+
}
6382
return (
6483
<CardFeature
6584
key={ id }
6685
title={ name }
6786
description={ description }
6887
icon={ INTEGRATION_ICONS[ id ] || DEFAULT_ICON }
6988
enabled={ isEnabled }
70-
enableLabel={ isSetUp ? __( 'Enable', 'newspack-plugin' ) : __( 'Connect', 'newspack-plugin' ) }
89+
requirements={ requirements }
90+
enableLabel={ enableLabel }
7191
configureLabel={ needsSetup ? __( 'Configure', 'newspack-plugin' ) : undefined }
72-
onEnable={ needsSetup ? goToSetup : () => onToggleEnabled( id, true ) }
92+
onEnable={ onEnable }
7393
onConfigure={ needsSetup ? goToSetup : () => history?.push( `/settings/${ id }` ) }
7494
moreControls={
7595
isEnabled

0 commit comments

Comments
 (0)