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

Social: Add connection management to the admin page #37120

Merged
merged 25 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b6d9c52
Prepare backend aggregation
gmjuhasz Apr 29, 2024
b47e440
Update store to use new format
gmjuhasz Apr 29, 2024
ece8d5f
Add component
gmjuhasz Apr 29, 2024
312e2e4
Update get_profile_link method
gmjuhasz Apr 29, 2024
9c255f1
changelog
gmjuhasz Apr 29, 2024
54883ca
Revert "Prepare backend aggregation"
manzoorwanijk May 2, 2024
0976a2a
Merge branch 'trunk' into add/social-connection-management-component
manzoorwanijk May 2, 2024
da25a06
Restore 'profile_link' prop
manzoorwanijk May 2, 2024
221fd6a
Use feature flag
gmjuhasz May 2, 2024
652b914
Fixup versions
gmjuhasz May 2, 2024
6680fdc
Create get_initial_state helper in publicize and use it in Jetpack an…
manzoorwanijk May 2, 2024
ce1a305
Restore admin page hasConnection logic
manzoorwanijk May 2, 2024
1ca294e
Fix the connection management for Jetpack and Social admin page
manzoorwanijk May 2, 2024
adad212
Restore connectionRefreshPath
manzoorwanijk May 2, 2024
3a5fa97
Fix stylelints
manzoorwanijk May 2, 2024
7aa408a
Fix the connection-test-results endpoint
manzoorwanijk May 2, 2024
7afa438
Fix PHP unit tests
manzoorwanijk May 2, 2024
e012385
Merge branch 'trunk' into add/social-connection-management-component
manzoorwanijk May 3, 2024
a100b5e
Replace deprecated method in tests
manzoorwanijk May 3, 2024
2e4d806
Fix mocking for PHP 7
manzoorwanijk May 3, 2024
c582ab2
Fix critical error
manzoorwanijk May 3, 2024
dd25185
No mocking needed now
manzoorwanijk May 3, 2024
d01a0bc
Set initial state only if publicize is enabled and setup
manzoorwanijk May 3, 2024
66b0aa6
Reload settings page if publicize is enabled
manzoorwanijk May 3, 2024
0e773f1
Use connection package instead of Jetpack class
manzoorwanijk May 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Social Admin page: Added connection management component
1 change: 1 addition & 0 deletions projects/js-packages/publicize-components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export { default as ReviewPrompt } from './src/components/review-prompt';
export { default as PostPublishReviewPrompt } from './src/components/post-publish-review-prompt';
export { default as PostPublishManualSharing } from './src/components/post-publish-manual-sharing';
export { default as RefreshJetpackSocialSettingsWrapper } from './src/components/refresh-jetpack-social-settings';
export { default as ConnectionManagement } from './src/components/connection-management';

export { default as useSocialMediaConnections } from './src/hooks/use-social-media-connections';
export { default as useSocialMediaMessage } from './src/hooks/use-social-media-message';
Expand Down
2 changes: 1 addition & 1 deletion projects/js-packages/publicize-components/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@automattic/jetpack-publicize-components",
"version": "0.49.4-alpha",
"version": "0.50.0-alpha",
"description": "A library of JS components required by the Publicize editor plugin",
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/publicize-components/#readme",
"bugs": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Button, Spinner } from '@automattic/jetpack-components';
import apiFetch from '@wordpress/api-fetch';
import { ExternalLink } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import classNames from 'classnames';
import { useCallback, useEffect } from 'react';
import useSocialMediaConnections from '../../hooks/use-social-media-connections';
import { store } from '../../social-store';
import ConnectionIcon from '../connection-icon';
import styles from './style.module.scss';

const ConnectionManagement = ( { className = null } ) => {
const { refresh } = useSocialMediaConnections();

const connections = useSelect( select => {
return select( store ).getConnections();
}, [] );

connections.sort( ( a, b ) => {
if ( a.service_name === b.service_name ) {
return a.connection_id.localeCompare( b.connection_id );
}
return a.service_name.localeCompare( b.service_name );
} );

// const [ isModalOpen, toggleModal ] = useReducer( state => ! state, false );

useEffect( () => {
refresh();
}, [ refresh ] );

const onDisconnect = useCallback(
conn_id => () => {
apiFetch( {
method: 'POST',
path: '/jetpack/v4/publicize/delete-connection/' + conn_id,
} ).then( () => {
// Handle disconnection
} );
},
[]
);

const renderConnectionName = connection => {
if ( connection.display_name ) {
if ( ! connection.profile_link ) {
return connection.display_name;
}
return (
<ExternalLink className={ styles[ 'profile-link' ] } href={ connection.profile_link }>
{ connection.display_name }
</ExternalLink>
);
}
return <Spinner color="black" />;
};

return (
<div className={ classNames( styles.wrapper, className ) }>
<h3>{ __( 'Connections', 'jetpack' ) }</h3>
{ connections.length ? (
<table>
<thead>
<tr>
<th className={ styles[ 'column-icon' ] }></th>
<th className={ styles[ 'column-name' ] }></th>
<th></th>
</tr>
</thead>
<tbody>
{ connections.map( connection => (
<tr className={ styles.item } key={ connection.connection_id }>
<td className={ styles.icon }>
<ConnectionIcon
serviceName={ connection.service_name }
label={ connection.display_name }
profilePicture={ connection.profile_picture }
/>
</td>
<td className={ styles.name }>{ renderConnectionName( connection ) }</td>
<td>
{ connection.can_disconnect && (
<Button
size="small"
variant="secondary"
onClick={ onDisconnect( connection.connection_id ) }
>
{ __( 'Disconnect', 'jetpack' ) }
</Button>
) }
</td>
</tr>
) ) }
</tbody>
</table>
) : (
<span>{ __( 'There are no connections added yet.', 'jetpack' ) }</span>
) }
<Button size="small">{ __( 'Add new connection', 'jetpack' ) }</Button>
{ /* { isModalOpen && <AddConnectionModal onCloseModal={ toggleModal } /> } */ }
</div>
);
};

export default ConnectionManagement;
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.wrapper {
display: flex;
flex-direction: column;
align-items: start;
gap: 1.5rem;

.profile-link {
&:global(.components-external-link) {
color: inherit;
text-decoration: none;

&:hover {
text-decoration: underline;
}

>svg {
vertical-align: bottom;
}
}
}
}

.name {
font-size: 15px;
}

.column-name {
width: 25rem;
}

.icon>div {
cursor: default;
}



// Table padding
td {
padding-top: 0.8rem;
padding-bottom: 0.8rem;

&:first-child {
padding-left: 1rem;
padding-right: 0.6rem;
}

&:last-child {
padding-right: 1rem;
}
}

// Table border
table {
border-collapse: separate;
border-spacing: 0;
border-radius: 4px;
outline: 1px solid var(--jp-gray-5);
}

tr:not(:last-child)>td {
border-bottom: solid 1px var(--jp-gray-5);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { getJetpackData } from '@automattic/jetpack-shared-extension-utils';
import apiFetch from '@wordpress/api-fetch';
import { store as editorStore } from '@wordpress/editor';
import { SET_CONNECTIONS, TOGGLE_CONNECTION } from './constants';
Expand Down Expand Up @@ -74,11 +73,9 @@ export function mergeConnections( freshConnections ) {
* @returns {Function} Refresh connection test results action.
*/
export function refreshConnectionTestResults( syncToMeta = false ) {
return async function ( { dispatch } ) {
return async function ( { dispatch, select } ) {
try {
const path =
getJetpackData()?.social?.connectionRefreshPath ||
'/wpcom/v2/publicize/connection-test-results';
const path = select.connectionRefreshPath() || '/wpcom/v2/publicize/connection-test-results';

const freshConnections = await apiFetch( { path } );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const reducer = combineReducers( {
hasPaidPlan: ( state = false ) => state,
userConnectionUrl: ( state = '' ) => state,
useAdminUiV1: ( state = false ) => state,
connectionRefreshPath: ( state = '' ) => state,
} );

export default reducer;
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ export function* getAutoConversionSettings() {
export function getConnections() {
return function ( { dispatch, registry } ) {
const editor = registry.select( editorStore );
if ( ! editor.getCurrentPostId() ) {
return;
}
// Get the initial connections from the post meta
const connections = editor.getEditedPostAttribute( 'jetpack_publicize_connections' );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const selectors = {
...autoConversionSettingsSelectors,
userConnectionUrl: state => state.userConnectionUrl,
useAdminUiV1: state => state.useAdminUiV1,
connectionRefreshPath: state => state.connectionRefreshPath,
};

export default selectors;
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export type Connection = {
connection_id: string;
is_healthy?: boolean;
error_code?: string;
can_disconnect: boolean;
profile_picture: string;
profile_link: string;
};

export type ConnectionData = {
Expand All @@ -41,6 +44,8 @@ export type SocialStoreState = {

declare global {
interface Window {
jetpackSocialInitialState?: SocialStoreState;
jetpackSocialInitialState?: SocialStoreState & {
is_publicize_enabled: boolean;
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Social Admin page: Added connection management component
2 changes: 1 addition & 1 deletion projects/packages/publicize/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"link-template": "https://github.com/Automattic/jetpack-publicize/compare/v${old}...v${new}"
},
"branch-alias": {
"dev-trunk": "0.42.x-dev"
"dev-trunk": "0.43.x-dev"
}
},
"config": {
Expand Down
2 changes: 1 addition & 1 deletion projects/packages/publicize/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@automattic/jetpack-publicize",
"version": "0.42.14-alpha",
"version": "0.43.0-alpha",
"description": "Publicize makes it easy to share your site’s posts on several social media networks automatically when you publish a new post.",
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/packages/publicize/#readme",
"bugs": {
Expand Down
12 changes: 12 additions & 0 deletions projects/packages/publicize/src/class-publicize-base.php
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,18 @@ public function get_profile_link( $service_name, $connection ) {
return 'https://facebook.com/' . $cmeta['connection_data']['meta']['facebook_page'];
}

if ( 'instagram-business' === $service_name && isset( $cmeta['connection_data']['meta']['username'] ) ) {
return 'https://instagram.com/' . $cmeta['connection_data']['meta']['username'];
}

if ( 'mastodon' === $service_name && isset( $cmeta['external_name'] ) ) {
return 'https://mastodon.social/@' . $cmeta['external_name'];
}

if ( 'nextdoor' === $service_name && isset( $cmeta['external_id'] ) ) {
return 'https://nextdoor.com/profile/' . $cmeta['external_id'];
}

if ( 'tumblr' === $service_name && isset( $cmeta['connection_data']['meta']['tumblr_base_hostname'] ) ) {
return 'https://' . $cmeta['connection_data']['meta']['tumblr_base_hostname'];
}
Expand Down
1 change: 1 addition & 0 deletions projects/packages/publicize/src/class-publicize.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ public function get_all_connections_for_user() {
'service_name' => $service_name,
'connection_id' => $connection['connection_data']['id'],
'can_disconnect' => current_user_can( 'manage_options' ) || get_current_user_id() === $user_id,
'profile_link' => $this->get_profile_link( $service_name, $connection ),
)
);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Automattic\Jetpack\Publicize\Jetpack_Social_Settings;

use Automattic\Jetpack\Connection\Manager;
use Automattic\Jetpack\Modules;
use Automattic\Jetpack\Publicize\Publicize;
use Automattic\Jetpack\Publicize\Social_Image_Generator\Templates;
Expand Down Expand Up @@ -170,8 +171,38 @@ public function get_settings( $with_available = false ) {
$settings['socialImageGeneratorSettings']['available'] = $this->is_sig_available();
}

return $settings;
}

/**
* Get the initial state.
*/
public function get_initial_state() {
global $publicize;

$settings = $this->get_settings( true );

$settings['useAdminUiV1'] = Publicize::use_admin_ui_v1();

$settings['is_publicize_enabled'] = false;

$connection = new Manager();

if ( ( new Modules() )->is_active( 'publicize' ) && $connection->has_connected_user() ) {
$settings['connectionData'] = array(
'connections' => $publicize->get_all_connections_for_user(),
'adminUrl' => esc_url_raw( $publicize->publicize_connections_url( 'jetpack-social-connections-admin-page' ) ),
);

$settings['is_publicize_enabled'] = true;
} else {
$settings['connectionData'] = array(
'connections' => array(),
);
}

$settings['connectionRefreshPath'] = '/jetpack/v4/publicize/connection-test-results';

return $settings;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ public function test_migrate_old_options() {
'enabled' => true,
'template' => 'example_template',
),
'useAdminUiV1' => false,
);

$this->settings = new SocialSettings();
Expand All @@ -140,7 +139,6 @@ public function test_migrate_old_options_with_missing() {
'enabled' => false,
'template' => Templates::DEFAULT_TEMPLATE,
),
'useAdminUiV1' => false,
);

$this->settings = new SocialSettings();
Expand Down
Loading
Loading