@automattic/jetpack-connection 0.39.18 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
### This is a list detailing changes for the Jetpack RNA Connection Component releases.
|
|
4
4
|
|
|
5
|
+
## [1.1.0] - 2025-06-04
|
|
6
|
+
### Added
|
|
7
|
+
- Improve error handling for protected owner on WordPress.com. [#43593]
|
|
8
|
+
|
|
9
|
+
## [1.0.0] - 2025-06-03
|
|
10
|
+
### Changed
|
|
11
|
+
- Update package dependencies. [#43718] [#43734]
|
|
12
|
+
|
|
5
13
|
## [0.39.18] - 2025-06-02
|
|
6
14
|
### Changed
|
|
7
15
|
- sass: `@use` rather than `@import` for `@wordpress/base-styles`. [#43607]
|
|
@@ -1040,6 +1048,8 @@
|
|
|
1040
1048
|
- `Main` and `ConnectUser` components added.
|
|
1041
1049
|
- `JetpackRestApiClient` API client added.
|
|
1042
1050
|
|
|
1051
|
+
[1.1.0]: https://github.com/Automattic/jetpack-connection-js/compare/v1.0.0...v1.1.0
|
|
1052
|
+
[1.0.0]: https://github.com/Automattic/jetpack-connection-js/compare/v0.39.18...v1.0.0
|
|
1043
1053
|
[0.39.18]: https://github.com/Automattic/jetpack-connection-js/compare/v0.39.17...v0.39.18
|
|
1044
1054
|
[0.39.17]: https://github.com/Automattic/jetpack-connection-js/compare/v0.39.16...v0.39.17
|
|
1045
1055
|
[0.39.16]: https://github.com/Automattic/jetpack-connection-js/compare/v0.39.15...v0.39.16
|
|
@@ -12,8 +12,13 @@ import styles from './styles.module.scss';
|
|
|
12
12
|
* @return {React.Component} The `ConnectionErrorNotice` component.
|
|
13
13
|
*/
|
|
14
14
|
const ConnectionErrorNotice = props => {
|
|
15
|
-
const {
|
|
16
|
-
|
|
15
|
+
const {
|
|
16
|
+
message,
|
|
17
|
+
isRestoringConnection,
|
|
18
|
+
restoreConnectionCallback,
|
|
19
|
+
restoreConnectionError,
|
|
20
|
+
actions = [], // New prop for custom actions
|
|
21
|
+
} = props;
|
|
17
22
|
|
|
18
23
|
const [ isBiggerThanMedium ] = useBreakpointMatch( [ 'md' ], [ '>' ] );
|
|
19
24
|
const wrapperClassName =
|
|
@@ -73,6 +78,39 @@ const ConnectionErrorNotice = props => {
|
|
|
73
78
|
</Notice>
|
|
74
79
|
) : null;
|
|
75
80
|
|
|
81
|
+
// Determine which actions to show
|
|
82
|
+
let actionButtons = [];
|
|
83
|
+
|
|
84
|
+
if ( actions.length > 0 ) {
|
|
85
|
+
// Use custom actions
|
|
86
|
+
actionButtons = actions.map( ( action, index ) => (
|
|
87
|
+
<a
|
|
88
|
+
key={ index }
|
|
89
|
+
onClick={ action.onClick }
|
|
90
|
+
onKeyDown={ action.onClick }
|
|
91
|
+
className={ `${ styles.button } ${ action.variant === 'primary' ? styles.primary : '' }` }
|
|
92
|
+
href="#"
|
|
93
|
+
>
|
|
94
|
+
{ action.isLoading
|
|
95
|
+
? action.loadingText || __( 'Loading…', 'jetpack-connection-js' )
|
|
96
|
+
: action.label }
|
|
97
|
+
</a>
|
|
98
|
+
) );
|
|
99
|
+
} else if ( restoreConnectionCallback ) {
|
|
100
|
+
// Use default restore connection action for backward compatibility
|
|
101
|
+
actionButtons = [
|
|
102
|
+
<a
|
|
103
|
+
key="restore"
|
|
104
|
+
onClick={ restoreConnectionCallback }
|
|
105
|
+
onKeyDown={ restoreConnectionCallback }
|
|
106
|
+
className={ styles.button }
|
|
107
|
+
href="#"
|
|
108
|
+
>
|
|
109
|
+
{ __( 'Restore Connection', 'jetpack-connection-js' ) }
|
|
110
|
+
</a>,
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
|
|
76
114
|
return (
|
|
77
115
|
<>
|
|
78
116
|
{ errorRender }
|
|
@@ -81,16 +119,7 @@ const ConnectionErrorNotice = props => {
|
|
|
81
119
|
{ icon }
|
|
82
120
|
{ message }
|
|
83
121
|
</div>
|
|
84
|
-
{
|
|
85
|
-
<a
|
|
86
|
-
onClick={ restoreConnectionCallback }
|
|
87
|
-
onKeyDown={ restoreConnectionCallback }
|
|
88
|
-
className={ styles.button }
|
|
89
|
-
href="#"
|
|
90
|
-
>
|
|
91
|
-
{ __( 'Restore Connection', 'jetpack-connection-js' ) }
|
|
92
|
-
</a>
|
|
93
|
-
) }
|
|
122
|
+
{ actionButtons.length > 0 && <div className={ styles.actions }>{ actionButtons }</div> }
|
|
94
123
|
</Notice>
|
|
95
124
|
</>
|
|
96
125
|
);
|
|
@@ -98,13 +127,23 @@ const ConnectionErrorNotice = props => {
|
|
|
98
127
|
|
|
99
128
|
ConnectionErrorNotice.propTypes = {
|
|
100
129
|
/** The notice message. */
|
|
101
|
-
message: PropTypes.string.isRequired,
|
|
130
|
+
message: PropTypes.oneOfType( [ PropTypes.string, PropTypes.element ] ).isRequired,
|
|
102
131
|
/** "Restore Connection" button callback. */
|
|
103
132
|
restoreConnectionCallback: PropTypes.func,
|
|
104
133
|
/** Whether connection restore is in progress. */
|
|
105
134
|
isRestoringConnection: PropTypes.bool,
|
|
106
135
|
/** The connection error text if there is one. */
|
|
107
136
|
restoreConnectionError: PropTypes.string,
|
|
137
|
+
/** Array of custom action objects. */
|
|
138
|
+
actions: PropTypes.arrayOf(
|
|
139
|
+
PropTypes.shape( {
|
|
140
|
+
label: PropTypes.string.isRequired,
|
|
141
|
+
onClick: PropTypes.func.isRequired,
|
|
142
|
+
isLoading: PropTypes.bool,
|
|
143
|
+
loadingText: PropTypes.string,
|
|
144
|
+
variant: PropTypes.oneOf( [ 'primary', 'secondary' ] ),
|
|
145
|
+
} )
|
|
146
|
+
),
|
|
108
147
|
};
|
|
109
148
|
|
|
110
149
|
export default ConnectionErrorNotice;
|
|
@@ -55,6 +55,16 @@
|
|
|
55
55
|
margin-top: 24px;
|
|
56
56
|
background: #000;
|
|
57
57
|
border-radius: var( --jp-border-radius );
|
|
58
|
+
|
|
59
|
+
&.primary {
|
|
60
|
+
background: var( --jp-green-50 );
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.actions {
|
|
65
|
+
display: flex;
|
|
66
|
+
gap: calc( var( --spacing-base ) * 2 ); // 16px
|
|
67
|
+
flex-wrap: wrap;
|
|
58
68
|
}
|
|
59
69
|
|
|
60
70
|
&.bigger-than-medium {
|
|
@@ -1,10 +1,39 @@
|
|
|
1
|
+
import { __ } from '@wordpress/i18n';
|
|
1
2
|
import ConnectionErrorNotice from '../../components/connection-error-notice';
|
|
2
3
|
import useConnection from '../../components/use-connection';
|
|
3
4
|
import useRestoreConnection from '../../hooks/use-restore-connection/index.jsx';
|
|
4
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Helper function to generate user creation URL with email prepopulation
|
|
8
|
+
*
|
|
9
|
+
* @param {object} connectionError - The connection error object
|
|
10
|
+
* @param {string} baseUrl - Base admin URL (defaults to '/wp-admin/')
|
|
11
|
+
* @return {string} The complete URL for user creation with email parameters
|
|
12
|
+
*/
|
|
13
|
+
export function getProtectedOwnerCreateAccountUrl( connectionError, baseUrl = '/wp-admin/' ) {
|
|
14
|
+
let redirectUrl = baseUrl + 'user-new.php';
|
|
15
|
+
|
|
16
|
+
// Add protected owner email if available for prepopulation
|
|
17
|
+
if ( connectionError?.error_data?.wpcom_user_email ) {
|
|
18
|
+
const params = new URLSearchParams( {
|
|
19
|
+
jetpack_protected_owner_email: connectionError.error_data.wpcom_user_email,
|
|
20
|
+
jetpack_create_missing_account: '1',
|
|
21
|
+
} );
|
|
22
|
+
redirectUrl += '?' + params.toString();
|
|
23
|
+
} else if ( connectionError?.error_data?.email ) {
|
|
24
|
+
const params = new URLSearchParams( {
|
|
25
|
+
jetpack_protected_owner_email: connectionError.error_data.email,
|
|
26
|
+
jetpack_create_missing_account: '1',
|
|
27
|
+
} );
|
|
28
|
+
redirectUrl += '?' + params.toString();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return redirectUrl;
|
|
32
|
+
}
|
|
33
|
+
|
|
5
34
|
/**
|
|
6
35
|
* Connection error notice hook.
|
|
7
|
-
* Returns
|
|
36
|
+
* Returns connection error data and conditional flag on whether
|
|
8
37
|
* to render the component or not.
|
|
9
38
|
*
|
|
10
39
|
* @return {object} - The hook data.
|
|
@@ -12,27 +41,90 @@ import useRestoreConnection from '../../hooks/use-restore-connection/index.jsx';
|
|
|
12
41
|
export default function useConnectionErrorNotice() {
|
|
13
42
|
const { connectionErrors } = useConnection( {} );
|
|
14
43
|
const connectionErrorList = Object.values( connectionErrors ).shift();
|
|
15
|
-
const
|
|
44
|
+
const firstError =
|
|
16
45
|
connectionErrorList &&
|
|
17
46
|
Object.values( connectionErrorList ).length &&
|
|
18
|
-
Object.values( connectionErrorList ).shift()
|
|
47
|
+
Object.values( connectionErrorList ).shift();
|
|
19
48
|
|
|
49
|
+
const connectionErrorMessage = firstError && firstError.error_message;
|
|
50
|
+
|
|
51
|
+
// Return all connection errors, including protected owner errors
|
|
20
52
|
const hasConnectionError = Boolean( connectionErrorMessage );
|
|
21
53
|
|
|
22
|
-
return {
|
|
54
|
+
return {
|
|
55
|
+
hasConnectionError,
|
|
56
|
+
connectionErrorMessage,
|
|
57
|
+
connectionError: firstError, // Full error object with error_type, etc.
|
|
58
|
+
connectionErrors, // All errors for advanced use cases
|
|
59
|
+
};
|
|
23
60
|
}
|
|
24
61
|
|
|
25
|
-
export const ConnectionError = (
|
|
26
|
-
|
|
62
|
+
export const ConnectionError = ( {
|
|
63
|
+
onCreateMissingAccount = null, // Custom handler for protected owner errors
|
|
64
|
+
trackingCallback = null, // Custom tracking function
|
|
65
|
+
customActions = null, // Function that returns custom actions based on error
|
|
66
|
+
} = {} ) => {
|
|
67
|
+
const { hasConnectionError, connectionErrorMessage, connectionError } =
|
|
68
|
+
useConnectionErrorNotice();
|
|
27
69
|
const { restoreConnection, isRestoringConnection, restoreConnectionError } =
|
|
28
70
|
useRestoreConnection();
|
|
29
71
|
|
|
30
|
-
|
|
72
|
+
if ( ! hasConnectionError ) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Determine error type
|
|
77
|
+
const isProtectedOwnerError = connectionError && connectionError.error_type === 'protected_owner';
|
|
78
|
+
|
|
79
|
+
// Build actions array based on error type
|
|
80
|
+
let actions = [];
|
|
81
|
+
|
|
82
|
+
if ( customActions ) {
|
|
83
|
+
// Use provided custom actions function
|
|
84
|
+
actions = customActions( connectionError, { restoreConnection, isRestoringConnection } );
|
|
85
|
+
} else if ( isProtectedOwnerError && onCreateMissingAccount ) {
|
|
86
|
+
// Handle protected owner error with custom handler
|
|
87
|
+
actions = [
|
|
88
|
+
{
|
|
89
|
+
label: __( 'Create missing account', 'jetpack-connection-js' ),
|
|
90
|
+
onClick: () => {
|
|
91
|
+
if ( trackingCallback ) {
|
|
92
|
+
trackingCallback( 'jetpack_connection_protected_owner_create_account_attempt', {} );
|
|
93
|
+
}
|
|
94
|
+
onCreateMissingAccount();
|
|
95
|
+
},
|
|
96
|
+
variant: 'primary',
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
} else if ( ! isProtectedOwnerError ) {
|
|
100
|
+
// Standard connection error - use restore connection
|
|
101
|
+
actions = [
|
|
102
|
+
{
|
|
103
|
+
label: __( 'Restore Connection', 'jetpack-connection-js' ),
|
|
104
|
+
onClick: () => {
|
|
105
|
+
if ( trackingCallback ) {
|
|
106
|
+
trackingCallback( 'jetpack_connection_error_notice_reconnect_cta_click', {} );
|
|
107
|
+
}
|
|
108
|
+
restoreConnection();
|
|
109
|
+
},
|
|
110
|
+
isLoading: isRestoringConnection,
|
|
111
|
+
loadingText: __( 'Reconnecting Jetpack…', 'jetpack-connection-js' ),
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// For protected owner errors without custom handler, don't show the component
|
|
117
|
+
if ( isProtectedOwnerError && ! onCreateMissingAccount && ! customActions ) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return (
|
|
31
122
|
<ConnectionErrorNotice
|
|
32
123
|
isRestoringConnection={ isRestoringConnection }
|
|
33
124
|
restoreConnectionError={ restoreConnectionError }
|
|
34
|
-
restoreConnectionCallback={ restoreConnection }
|
|
125
|
+
restoreConnectionCallback={ actions.length === 0 ? restoreConnection : null } // Fallback for backward compatibility
|
|
35
126
|
message={ connectionErrorMessage }
|
|
127
|
+
actions={ actions }
|
|
36
128
|
/>
|
|
37
|
-
)
|
|
129
|
+
);
|
|
38
130
|
};
|
package/index.jsx
CHANGED
|
@@ -49,4 +49,7 @@ export { STORE_ID as CONNECTION_STORE_ID } from './state/store';
|
|
|
49
49
|
*/
|
|
50
50
|
export { default as useProductCheckoutWorkflow } from './hooks/use-product-checkout-workflow';
|
|
51
51
|
export { default as useRestoreConnection } from './hooks/use-restore-connection';
|
|
52
|
-
export {
|
|
52
|
+
export {
|
|
53
|
+
default as useConnectionErrorNotice,
|
|
54
|
+
getProtectedOwnerCreateAccountUrl,
|
|
55
|
+
} from './hooks/use-connection-error-notice';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/jetpack-connection",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Jetpack Connection Component",
|
|
5
5
|
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/connection/#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
"author": "Automattic",
|
|
15
15
|
"license": "GPL-2.0-or-later",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@automattic/jetpack-analytics": "^0.
|
|
18
|
-
"@automattic/jetpack-api": "^0.
|
|
19
|
-
"@automattic/jetpack-components": "^
|
|
20
|
-
"@automattic/jetpack-config": "^0.
|
|
17
|
+
"@automattic/jetpack-analytics": "^1.0.0",
|
|
18
|
+
"@automattic/jetpack-api": "^1.0.0",
|
|
19
|
+
"@automattic/jetpack-components": "^1.1.0",
|
|
20
|
+
"@automattic/jetpack-config": "^1.0.0",
|
|
21
21
|
"@automattic/jetpack-script-data": "^0.4.2",
|
|
22
22
|
"@wordpress/base-styles": "6.0.0",
|
|
23
23
|
"@wordpress/browserslist-config": "6.24.0",
|
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
"prop-types": "^15.7.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@automattic/jetpack-base-styles": "^0.
|
|
35
|
-
"@babel/core": "7.
|
|
36
|
-
"@babel/preset-react": "7.
|
|
34
|
+
"@automattic/jetpack-base-styles": "^1.0.0",
|
|
35
|
+
"@babel/core": "7.27.4",
|
|
36
|
+
"@babel/preset-react": "7.27.1",
|
|
37
37
|
"@storybook/addon-actions": "8.6.7",
|
|
38
38
|
"@testing-library/dom": "10.4.0",
|
|
39
39
|
"@testing-library/react": "16.2.0",
|
|
40
40
|
"@testing-library/user-event": "14.6.1",
|
|
41
|
-
"@types/react": "18.3.
|
|
41
|
+
"@types/react": "18.3.23",
|
|
42
42
|
"jest": "29.7.0",
|
|
43
43
|
"jest-environment-jsdom": "29.7.0",
|
|
44
44
|
"react": "18.3.1",
|