@automattic/jetpack-connection 0.36.7 → 0.37.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 +9 -0
- package/components/manage-connection-dialog/index.jsx +165 -21
- package/components/manage-connection-dialog/style.scss +25 -2
- package/components/owner-disconnect-dialog/index.jsx +233 -0
- package/components/owner-disconnect-dialog/style.scss +14 -0
- package/package.json +9 -9
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
|
+
## [0.37.0] - 2025-02-24
|
|
6
|
+
### Added
|
|
7
|
+
- Warn that disconnecting owner account will disconnect all other users first. [#41923]
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- Move the API endpoint for unlinking the user to the automattic/jetpack-connection package. [#41398]
|
|
11
|
+
- Update package dependencies. [#41955]
|
|
12
|
+
|
|
5
13
|
## [0.36.7] - 2025-02-17
|
|
6
14
|
### Changed
|
|
7
15
|
- Update dependencies.
|
|
@@ -934,6 +942,7 @@
|
|
|
934
942
|
- `Main` and `ConnectUser` components added.
|
|
935
943
|
- `JetpackRestApiClient` API client added.
|
|
936
944
|
|
|
945
|
+
[0.37.0]: https://github.com/Automattic/jetpack-connection-js/compare/v0.36.7...v0.37.0
|
|
937
946
|
[0.36.7]: https://github.com/Automattic/jetpack-connection-js/compare/v0.36.6...v0.36.7
|
|
938
947
|
[0.36.6]: https://github.com/Automattic/jetpack-connection-js/compare/v0.36.5...v0.36.6
|
|
939
948
|
[0.36.5]: https://github.com/Automattic/jetpack-connection-js/compare/v0.36.4...v0.36.5
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
+
import jetpackAnalytics from '@automattic/jetpack-analytics';
|
|
5
|
+
import restApi from '@automattic/jetpack-api';
|
|
4
6
|
import { Button, getRedirectUrl, Text } from '@automattic/jetpack-components';
|
|
5
7
|
import { ExternalLink, Modal } from '@wordpress/components';
|
|
6
8
|
import { createInterpolateElement } from '@wordpress/element';
|
|
@@ -8,11 +10,13 @@ import { __ } from '@wordpress/i18n';
|
|
|
8
10
|
import { Icon, chevronRight, external } from '@wordpress/icons';
|
|
9
11
|
import clsx from 'clsx';
|
|
10
12
|
import PropTypes from 'prop-types';
|
|
11
|
-
import React, { useCallback, useState } from 'react';
|
|
13
|
+
import React, { useCallback, useEffect, useState, useMemo } from 'react';
|
|
12
14
|
/**
|
|
13
15
|
* Internal dependencies
|
|
14
16
|
*/
|
|
17
|
+
import ConnectionErrorNotice from '../connection-error-notice/index.jsx';
|
|
15
18
|
import DisconnectDialog from '../disconnect-dialog';
|
|
19
|
+
import OwnerDisconnectDialog from '../owner-disconnect-dialog';
|
|
16
20
|
import './style.scss';
|
|
17
21
|
|
|
18
22
|
/**
|
|
@@ -28,6 +32,7 @@ const ManageConnectionDialog = props => {
|
|
|
28
32
|
apiNonce,
|
|
29
33
|
connectedPlugins,
|
|
30
34
|
onDisconnected,
|
|
35
|
+
onUnlinked,
|
|
31
36
|
context = 'jetpack-dashboard',
|
|
32
37
|
connectedUser = {}, // Pass empty object to avoid undefined errors.
|
|
33
38
|
connectedSiteId,
|
|
@@ -36,6 +41,17 @@ const ManageConnectionDialog = props => {
|
|
|
36
41
|
} = props;
|
|
37
42
|
|
|
38
43
|
const [ isDisconnectDialogOpen, setIsDisconnectDialogOpen ] = useState( false );
|
|
44
|
+
const [ isDisconnectingUser, setIsDisconnectingUser ] = useState( false );
|
|
45
|
+
const [ unlinkError, setUnlinkError ] = useState( '' );
|
|
46
|
+
const [ isOwnerDisconnectDialogOpen, setIsOwnerDisconnectDialogOpen ] = useState( false );
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Initialize the REST API.
|
|
50
|
+
*/
|
|
51
|
+
useEffect( () => {
|
|
52
|
+
restApi.setApiRoot( apiRoot );
|
|
53
|
+
restApi.setApiNonce( apiNonce );
|
|
54
|
+
}, [ apiRoot, apiNonce ] );
|
|
39
55
|
|
|
40
56
|
/**
|
|
41
57
|
* Open the Disconnect Dialog.
|
|
@@ -59,6 +75,82 @@ const ManageConnectionDialog = props => {
|
|
|
59
75
|
[ setIsDisconnectDialogOpen ]
|
|
60
76
|
);
|
|
61
77
|
|
|
78
|
+
const isCurrentUserAdmin = useMemo( () => {
|
|
79
|
+
return !! connectedUser.currentUser?.permissions?.manage_options;
|
|
80
|
+
}, [ connectedUser.currentUser ] );
|
|
81
|
+
|
|
82
|
+
const _disconnectUser = useCallback( () => {
|
|
83
|
+
// Not connected to WPCOM? bail.
|
|
84
|
+
if ( ! connectedUser.currentUser?.isConnected ) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
setIsDisconnectingUser( true );
|
|
89
|
+
setUnlinkError( '' );
|
|
90
|
+
|
|
91
|
+
restApi
|
|
92
|
+
// Passing true to unlink will force the user disconnection
|
|
93
|
+
// This is needed for an admin to disconnect themselves
|
|
94
|
+
.unlinkUser( isCurrentUserAdmin )
|
|
95
|
+
.then( () => {
|
|
96
|
+
setIsDisconnectingUser( false );
|
|
97
|
+
onClose();
|
|
98
|
+
onUnlinked();
|
|
99
|
+
} )
|
|
100
|
+
.catch( () => {
|
|
101
|
+
let errorMessage = __(
|
|
102
|
+
'There was some trouble disconnecting your user account, your Jetpack plugin(s) may be outdated. Please visit your plugins page and make sure all Jetpack plugins are updated.',
|
|
103
|
+
'jetpack-connection-js'
|
|
104
|
+
);
|
|
105
|
+
if ( ! isCurrentUserAdmin ) {
|
|
106
|
+
errorMessage = __(
|
|
107
|
+
'There was some trouble disconnecting your user account, your Jetpack plugin(s) may be outdated. Please ask a site admin to update Jetpack',
|
|
108
|
+
'jetpack-connection-js'
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
setUnlinkError( errorMessage );
|
|
112
|
+
setIsDisconnectingUser( false );
|
|
113
|
+
} );
|
|
114
|
+
}, [
|
|
115
|
+
setIsDisconnectingUser,
|
|
116
|
+
setUnlinkError,
|
|
117
|
+
isCurrentUserAdmin,
|
|
118
|
+
onUnlinked,
|
|
119
|
+
onClose,
|
|
120
|
+
connectedUser,
|
|
121
|
+
] );
|
|
122
|
+
|
|
123
|
+
const handleDisconnectUser = useCallback(
|
|
124
|
+
e => {
|
|
125
|
+
e && e.preventDefault();
|
|
126
|
+
|
|
127
|
+
// If user is connection owner, show warning modal instead of disconnecting
|
|
128
|
+
if ( connectedUser.currentUser?.isMaster ) {
|
|
129
|
+
setIsOwnerDisconnectDialogOpen( true );
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Existing disconnect logic for non-owners
|
|
134
|
+
jetpackAnalytics.tracks.recordEvent(
|
|
135
|
+
'jetpack_manage_connection_dialog_disconnect_user_click',
|
|
136
|
+
{ context: context }
|
|
137
|
+
);
|
|
138
|
+
_disconnectUser();
|
|
139
|
+
},
|
|
140
|
+
[ _disconnectUser, context, connectedUser ]
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const isControlsDisabled = useMemo( () => {
|
|
144
|
+
return isDisconnectingUser;
|
|
145
|
+
}, [ isDisconnectingUser ] );
|
|
146
|
+
|
|
147
|
+
// This is silly, but it's an optimizer workaround
|
|
148
|
+
const disconnectingText = __( 'Disconnecting…', 'jetpack-connection-js' );
|
|
149
|
+
|
|
150
|
+
const handleCloseOwnerDialog = useCallback( () => {
|
|
151
|
+
setIsOwnerDisconnectDialogOpen( false );
|
|
152
|
+
}, [ setIsOwnerDisconnectDialogOpen ] );
|
|
153
|
+
|
|
62
154
|
return (
|
|
63
155
|
<>
|
|
64
156
|
{ isOpen && (
|
|
@@ -82,22 +174,47 @@ const ManageConnectionDialog = props => {
|
|
|
82
174
|
'jetpack-connection-js'
|
|
83
175
|
) }
|
|
84
176
|
</Text>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
177
|
+
{ isCurrentUserAdmin &&
|
|
178
|
+
connectedUser.currentUser?.isConnected &&
|
|
179
|
+
connectedUser.currentUser?.isMaster && (
|
|
180
|
+
<ManageConnectionActionCard
|
|
181
|
+
title={ __( 'Transfer ownership to another admin', 'jetpack-connection-js' ) }
|
|
182
|
+
link={ getRedirectUrl( 'calypso-settings-manage-connection', {
|
|
183
|
+
site: window?.myJetpackInitialState?.siteSuffix,
|
|
184
|
+
} ) }
|
|
185
|
+
isExternal={ true }
|
|
186
|
+
key="transfer"
|
|
187
|
+
action="transfer"
|
|
188
|
+
disabled={ isControlsDisabled }
|
|
189
|
+
/>
|
|
190
|
+
) }
|
|
191
|
+
{ connectedUser.currentUser?.isConnected && (
|
|
192
|
+
<>
|
|
193
|
+
{ '' !== unlinkError && <ConnectionErrorNotice message={ unlinkError } /> }
|
|
194
|
+
<ManageConnectionActionCard
|
|
195
|
+
title={
|
|
196
|
+
isDisconnectingUser
|
|
197
|
+
? disconnectingText
|
|
198
|
+
: __( 'Disconnect my user account', 'jetpack-connection-js' )
|
|
199
|
+
}
|
|
200
|
+
onClick={ handleDisconnectUser }
|
|
201
|
+
key="unlink"
|
|
202
|
+
action="unlink"
|
|
203
|
+
disabled={ isControlsDisabled }
|
|
204
|
+
/>
|
|
205
|
+
</>
|
|
206
|
+
) }
|
|
207
|
+
{ isCurrentUserAdmin && (
|
|
208
|
+
<ManageConnectionActionCard
|
|
209
|
+
title={ __( 'Disconnect Jetpack', 'jetpack-connection-js' ) }
|
|
210
|
+
onClick={ openDisconnectDialog }
|
|
211
|
+
key="disconnect"
|
|
212
|
+
action="disconnect"
|
|
213
|
+
disabled={ isControlsDisabled }
|
|
214
|
+
/>
|
|
215
|
+
) }
|
|
99
216
|
</div>
|
|
100
|
-
<HelpFooter onClose={ onClose } />
|
|
217
|
+
<HelpFooter onClose={ onClose } disabled={ isControlsDisabled } />
|
|
101
218
|
</Modal>
|
|
102
219
|
|
|
103
220
|
<DisconnectDialog
|
|
@@ -111,24 +228,48 @@ const ManageConnectionDialog = props => {
|
|
|
111
228
|
onClose={ closeDisconnectDialog }
|
|
112
229
|
context={ context }
|
|
113
230
|
/>
|
|
231
|
+
|
|
232
|
+
<OwnerDisconnectDialog
|
|
233
|
+
isOpen={ isOwnerDisconnectDialogOpen }
|
|
234
|
+
onClose={ handleCloseOwnerDialog }
|
|
235
|
+
apiRoot={ apiRoot }
|
|
236
|
+
apiNonce={ apiNonce }
|
|
237
|
+
onDisconnected={ onDisconnected }
|
|
238
|
+
onUnlinked={ onUnlinked }
|
|
239
|
+
/>
|
|
114
240
|
</>
|
|
115
241
|
) }
|
|
116
242
|
</>
|
|
117
243
|
);
|
|
118
244
|
};
|
|
119
245
|
|
|
120
|
-
const ManageConnectionActionCard = ( {
|
|
246
|
+
const ManageConnectionActionCard = ( {
|
|
247
|
+
title,
|
|
248
|
+
onClick = () => null,
|
|
249
|
+
isExternal = false,
|
|
250
|
+
link = '#',
|
|
251
|
+
action,
|
|
252
|
+
disabled = false,
|
|
253
|
+
} ) => {
|
|
254
|
+
const disabledCallback = useCallback( e => e.preventDefault(), [] );
|
|
255
|
+
|
|
121
256
|
return (
|
|
122
|
-
<div
|
|
257
|
+
<div
|
|
258
|
+
className={
|
|
259
|
+
'jp-connection__manage-dialog__action-card card' + ( disabled ? ' disabled' : '' )
|
|
260
|
+
}
|
|
261
|
+
>
|
|
123
262
|
<div className="jp-connection__manage-dialog__action-card__card-content">
|
|
124
263
|
<a
|
|
125
264
|
href={ link }
|
|
126
265
|
className={ clsx( 'jp-connection__manage-dialog__action-card__card-headline', action ) }
|
|
127
|
-
onClick={ onClick }
|
|
266
|
+
onClick={ ! disabled ? onClick : disabledCallback }
|
|
267
|
+
target={ isExternal ? '_blank' : '_self' }
|
|
268
|
+
rel={ 'noopener noreferrer' }
|
|
128
269
|
>
|
|
129
270
|
{ title }
|
|
130
271
|
<Icon
|
|
131
|
-
icon={
|
|
272
|
+
icon={ isExternal ? external : chevronRight }
|
|
132
273
|
className="jp-connection__manage-dialog__action-card__icon"
|
|
133
274
|
/>
|
|
134
275
|
</a>
|
|
@@ -137,7 +278,7 @@ const ManageConnectionActionCard = ( { title, onClick = () => null, link = '#',
|
|
|
137
278
|
);
|
|
138
279
|
};
|
|
139
280
|
|
|
140
|
-
const HelpFooter = ( { onClose } ) => {
|
|
281
|
+
const HelpFooter = ( { onClose, disabled } ) => {
|
|
141
282
|
return (
|
|
142
283
|
<div className="jp-row jp-connection__manage-dialog__actions">
|
|
143
284
|
<div className="jp-connection__manage-dialog__text-wrap lg-col-span-9 md-col-span-7 sm-col-span-3">
|
|
@@ -175,6 +316,7 @@ const HelpFooter = ( { onClose } ) => {
|
|
|
175
316
|
variant="secondary"
|
|
176
317
|
onClick={ onClose }
|
|
177
318
|
className="jp-connection__manage-dialog__btn-dismiss"
|
|
319
|
+
disabled={ disabled }
|
|
178
320
|
>
|
|
179
321
|
{ __( 'Cancel', 'jetpack-connection-js' ) }
|
|
180
322
|
</Button>
|
|
@@ -194,6 +336,8 @@ ManageConnectionDialog.propTypes = {
|
|
|
194
336
|
connectedPlugins: PropTypes.oneOfType( [ PropTypes.array, PropTypes.object ] ),
|
|
195
337
|
/** The callback to be called upon disconnection success. */
|
|
196
338
|
onDisconnected: PropTypes.func,
|
|
339
|
+
/** The callback to be called upon user unlink success. */
|
|
340
|
+
onUnlinked: PropTypes.func,
|
|
197
341
|
/** The context in which this component is being used. */
|
|
198
342
|
context: PropTypes.string,
|
|
199
343
|
/** An object representing the connected user. */
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
// shorthand intentionally not used here for overriding the .reset class
|
|
27
|
+
.jp-connection__manage-dialog__large-text {
|
|
27
28
|
margin-top: calc( var( --spacing-base ) * 3 );
|
|
28
29
|
margin-bottom: calc( var( --spacing-base ) * 4 );
|
|
29
30
|
max-width: 60%;
|
|
@@ -70,6 +71,7 @@
|
|
|
70
71
|
margin: var( --spacing-base ) auto;
|
|
71
72
|
text-align: left;
|
|
72
73
|
border: none;
|
|
74
|
+
position: relative;
|
|
73
75
|
|
|
74
76
|
&__card-headline {
|
|
75
77
|
font-size: var( --font-body );
|
|
@@ -82,7 +84,20 @@
|
|
|
82
84
|
float:right;
|
|
83
85
|
}
|
|
84
86
|
|
|
85
|
-
|
|
87
|
+
&.disabled:before {
|
|
88
|
+
content: '';
|
|
89
|
+
display: block;
|
|
90
|
+
position: absolute;
|
|
91
|
+
top: 0;
|
|
92
|
+
left: 0;
|
|
93
|
+
width: 100%;
|
|
94
|
+
height: 100%;
|
|
95
|
+
opacity: 25%;
|
|
96
|
+
border-radius: 3px;
|
|
97
|
+
background: var( --jp-black );
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.transfer, .unlink {
|
|
86
101
|
color:var( --jp-black );
|
|
87
102
|
fill: var( --jp-black );
|
|
88
103
|
}
|
|
@@ -91,6 +106,14 @@
|
|
|
91
106
|
color: var( --jp-red );
|
|
92
107
|
fill: var( --jp-red );
|
|
93
108
|
}
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.components-notice {
|
|
113
|
+
width: 750px;
|
|
114
|
+
max-width: 100%;
|
|
115
|
+
margin: var( --spacing-base ) auto;
|
|
116
|
+
text-align: left;
|
|
94
117
|
}
|
|
95
118
|
|
|
96
119
|
.components-modal {
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import jetpackAnalytics from '@automattic/jetpack-analytics';
|
|
5
|
+
import restApi from '@automattic/jetpack-api';
|
|
6
|
+
import { getRedirectUrl } from '@automattic/jetpack-components';
|
|
7
|
+
import { ExternalLink, Modal, Button } from '@wordpress/components';
|
|
8
|
+
import { createInterpolateElement } from '@wordpress/element';
|
|
9
|
+
import { __ } from '@wordpress/i18n';
|
|
10
|
+
import { Icon, chevronRight, external } from '@wordpress/icons';
|
|
11
|
+
import clsx from 'clsx';
|
|
12
|
+
import PropTypes from 'prop-types';
|
|
13
|
+
import React, { useCallback, useState, useEffect } from 'react';
|
|
14
|
+
import './style.scss';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The Owner Disconnect Dialog component.
|
|
18
|
+
*
|
|
19
|
+
* @param {object} props - Component props.
|
|
20
|
+
* @param {boolean} props.isOpen - Whether the dialog is open.
|
|
21
|
+
* @param {Function} props.onClose - Callback for when the dialog is closed.
|
|
22
|
+
* @param {string} props.apiRoot - API root URL.
|
|
23
|
+
* @param {string} props.apiNonce - API nonce.
|
|
24
|
+
* @param {Function} props.onDisconnected - Callback after successful disconnection.
|
|
25
|
+
* @param {Function} props.onUnlinked - Callback after user is unlinked.
|
|
26
|
+
* @return {React.Component} The OwnerDisconnectDialog component.
|
|
27
|
+
*/
|
|
28
|
+
const OwnerDisconnectDialog = ( {
|
|
29
|
+
isOpen,
|
|
30
|
+
onClose,
|
|
31
|
+
apiRoot,
|
|
32
|
+
apiNonce,
|
|
33
|
+
onDisconnected,
|
|
34
|
+
onUnlinked,
|
|
35
|
+
} ) => {
|
|
36
|
+
// Add state for disconnect status and error
|
|
37
|
+
const [ isDisconnecting, setIsDisconnecting ] = useState( false );
|
|
38
|
+
const [ disconnectError, setDisconnectError ] = useState( '' );
|
|
39
|
+
|
|
40
|
+
// Add these string constants
|
|
41
|
+
const disconnectingText = __( 'Disconnecting…', 'jetpack-connection-js' );
|
|
42
|
+
const disconnectText = __( 'Disconnect', 'jetpack-connection-js' );
|
|
43
|
+
|
|
44
|
+
// Initialize the REST API
|
|
45
|
+
useEffect( () => {
|
|
46
|
+
restApi.setApiRoot( apiRoot );
|
|
47
|
+
restApi.setApiNonce( apiNonce );
|
|
48
|
+
}, [ apiRoot, apiNonce ] );
|
|
49
|
+
|
|
50
|
+
const handleStayConnected = useCallback( () => {
|
|
51
|
+
onClose();
|
|
52
|
+
}, [ onClose ] );
|
|
53
|
+
|
|
54
|
+
const handleDisconnectAnyway = useCallback( () => {
|
|
55
|
+
// Track disconnect click
|
|
56
|
+
jetpackAnalytics.tracks.recordEvent(
|
|
57
|
+
'jetpack_manage_connection_dialog_owner_disconnect_click'
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
setIsDisconnecting( true );
|
|
61
|
+
setDisconnectError( '' );
|
|
62
|
+
|
|
63
|
+
// Disconnect owner with force and disconnect-all-users parameters
|
|
64
|
+
restApi
|
|
65
|
+
.unlinkUser( true, { disconnectAllUsers: true } )
|
|
66
|
+
.then( () => {
|
|
67
|
+
// Track successful disconnect
|
|
68
|
+
jetpackAnalytics.tracks.recordEvent(
|
|
69
|
+
'jetpack_manage_connection_dialog_owner_disconnect_success'
|
|
70
|
+
);
|
|
71
|
+
// Don't close modal or change state since page will reload
|
|
72
|
+
onDisconnected && onDisconnected();
|
|
73
|
+
onUnlinked && onUnlinked();
|
|
74
|
+
} )
|
|
75
|
+
.catch( () => {
|
|
76
|
+
// Track failed disconnect
|
|
77
|
+
jetpackAnalytics.tracks.recordEvent(
|
|
78
|
+
'jetpack_manage_connection_dialog_owner_disconnect_error'
|
|
79
|
+
);
|
|
80
|
+
setDisconnectError(
|
|
81
|
+
__(
|
|
82
|
+
'There was a problem disconnecting your account. Please try again.',
|
|
83
|
+
'jetpack-connection-js'
|
|
84
|
+
)
|
|
85
|
+
);
|
|
86
|
+
setIsDisconnecting( false );
|
|
87
|
+
} );
|
|
88
|
+
}, [ onDisconnected, onUnlinked ] );
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
isOpen && (
|
|
92
|
+
<Modal
|
|
93
|
+
title=""
|
|
94
|
+
contentLabel={ __( 'Disconnect Owner Account', 'jetpack-connection-js' ) }
|
|
95
|
+
aria={ {
|
|
96
|
+
labelledby: 'jp-connection__disconnect-dialog__heading',
|
|
97
|
+
} }
|
|
98
|
+
onRequestClose={ handleStayConnected }
|
|
99
|
+
className="jp-connection__disconnect-dialog"
|
|
100
|
+
>
|
|
101
|
+
<div className="jp-connection__disconnect-dialog__content">
|
|
102
|
+
<h1 id="jp-connection__disconnect-dialog__heading">
|
|
103
|
+
{ __( 'Disconnect Owner Account', 'jetpack-connection-js' ) }
|
|
104
|
+
</h1>
|
|
105
|
+
<p className="jp-connection__disconnect-dialog__large-text">
|
|
106
|
+
{ __(
|
|
107
|
+
'Disconnecting the owner account will remove the Jetpack connection for all users on this site. The site will remain connected.',
|
|
108
|
+
'jetpack-connection-js'
|
|
109
|
+
) }
|
|
110
|
+
</p>
|
|
111
|
+
<ManageConnectionActionCard
|
|
112
|
+
title={ __( 'Transfer ownership to another admin', 'jetpack-connection-js' ) }
|
|
113
|
+
link={ getRedirectUrl( 'calypso-settings-manage-connection', {
|
|
114
|
+
site: window?.myJetpackInitialState?.siteSuffix,
|
|
115
|
+
} ) }
|
|
116
|
+
isExternal={ true }
|
|
117
|
+
action="transfer"
|
|
118
|
+
/>
|
|
119
|
+
<ManageConnectionActionCard
|
|
120
|
+
title={ __( 'View other connected accounts', 'jetpack-connection-js' ) }
|
|
121
|
+
link="users.php"
|
|
122
|
+
action="check-users"
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<div className="jp-connection__disconnect-dialog__actions">
|
|
127
|
+
<div className="jp-row">
|
|
128
|
+
<div className="lg-col-span-8 md-col-span-9 sm-col-span-4">
|
|
129
|
+
<p>
|
|
130
|
+
{ createInterpolateElement(
|
|
131
|
+
__(
|
|
132
|
+
'<strong>Need help?</strong> Learn more about the <connectionInfoLink>Jetpack connection</connectionInfoLink> or <supportLink>contact Jetpack support</supportLink>',
|
|
133
|
+
'jetpack-connection-js'
|
|
134
|
+
),
|
|
135
|
+
{
|
|
136
|
+
strong: <strong></strong>,
|
|
137
|
+
connectionInfoLink: (
|
|
138
|
+
<ExternalLink
|
|
139
|
+
href={ getRedirectUrl(
|
|
140
|
+
'why-the-wordpress-com-connection-is-important-for-jetpack'
|
|
141
|
+
) }
|
|
142
|
+
className="jp-connection__disconnect-dialog__link"
|
|
143
|
+
/>
|
|
144
|
+
),
|
|
145
|
+
supportLink: (
|
|
146
|
+
<ExternalLink
|
|
147
|
+
href={ getRedirectUrl( 'jetpack-support' ) }
|
|
148
|
+
className="jp-connection__disconnect-dialog__link"
|
|
149
|
+
/>
|
|
150
|
+
),
|
|
151
|
+
}
|
|
152
|
+
) }
|
|
153
|
+
</p>
|
|
154
|
+
</div>
|
|
155
|
+
<div className="jp-connection__disconnect-dialog__button-wrap lg-col-span-4 md-col-span-7 sm-col-span-4">
|
|
156
|
+
<Button
|
|
157
|
+
variant="primary"
|
|
158
|
+
onClick={ handleStayConnected }
|
|
159
|
+
className="jp-connection__disconnect-dialog__btn-dismiss"
|
|
160
|
+
>
|
|
161
|
+
{ __( 'Stay Connected', 'jetpack-connection-js' ) }
|
|
162
|
+
</Button>
|
|
163
|
+
<Button
|
|
164
|
+
variant="primary"
|
|
165
|
+
onClick={ handleDisconnectAnyway }
|
|
166
|
+
className="jp-connection__disconnect-dialog__btn-disconnect"
|
|
167
|
+
isDestructive
|
|
168
|
+
disabled={ isDisconnecting }
|
|
169
|
+
>
|
|
170
|
+
{ isDisconnecting ? disconnectingText : disconnectText }
|
|
171
|
+
</Button>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
{ disconnectError && (
|
|
175
|
+
<p className="jp-connection__disconnect-dialog__error">{ disconnectError }</p>
|
|
176
|
+
) }
|
|
177
|
+
</div>
|
|
178
|
+
</Modal>
|
|
179
|
+
)
|
|
180
|
+
);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
OwnerDisconnectDialog.propTypes = {
|
|
184
|
+
/** Whether the dialog is open */
|
|
185
|
+
isOpen: PropTypes.bool,
|
|
186
|
+
/** Callback for when the dialog is closed */
|
|
187
|
+
onClose: PropTypes.func,
|
|
188
|
+
/** API root URL */
|
|
189
|
+
apiRoot: PropTypes.string.isRequired,
|
|
190
|
+
/** API nonce */
|
|
191
|
+
apiNonce: PropTypes.string.isRequired,
|
|
192
|
+
/** Callback after successful disconnection */
|
|
193
|
+
onDisconnected: PropTypes.func,
|
|
194
|
+
/** Callback after user is unlinked */
|
|
195
|
+
onUnlinked: PropTypes.func,
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const ManageConnectionActionCard = ( {
|
|
199
|
+
title,
|
|
200
|
+
onClick = () => null,
|
|
201
|
+
isExternal = false,
|
|
202
|
+
link = '#',
|
|
203
|
+
action,
|
|
204
|
+
disabled = false,
|
|
205
|
+
} ) => {
|
|
206
|
+
const disabledCallback = useCallback( e => e.preventDefault(), [] );
|
|
207
|
+
|
|
208
|
+
return (
|
|
209
|
+
<div
|
|
210
|
+
className={
|
|
211
|
+
'jp-connection__manage-dialog__action-card card' + ( disabled ? ' disabled' : '' )
|
|
212
|
+
}
|
|
213
|
+
>
|
|
214
|
+
<div className="jp-connection__manage-dialog__action-card__card-content">
|
|
215
|
+
<a
|
|
216
|
+
href={ link }
|
|
217
|
+
className={ clsx( 'jp-connection__manage-dialog__action-card__card-headline', action ) }
|
|
218
|
+
onClick={ ! disabled ? onClick : disabledCallback }
|
|
219
|
+
target={ isExternal ? '_blank' : '_self' }
|
|
220
|
+
rel={ 'noopener noreferrer' }
|
|
221
|
+
>
|
|
222
|
+
{ title }
|
|
223
|
+
<Icon
|
|
224
|
+
icon={ isExternal ? external : chevronRight }
|
|
225
|
+
className="jp-connection__manage-dialog__action-card__icon"
|
|
226
|
+
/>
|
|
227
|
+
</a>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export default OwnerDisconnectDialog;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.jp-connection__disconnect-dialog {
|
|
2
|
+
// Add !important to override WordPress styles
|
|
3
|
+
.components-button.jp-connection__disconnect-dialog__btn-dismiss {
|
|
4
|
+
background: var( --jp-black ) !important;
|
|
5
|
+
}
|
|
6
|
+
.jp-connection__disconnect-dialog__content {
|
|
7
|
+
--spacing-base: 8px;
|
|
8
|
+
}
|
|
9
|
+
.jp-connection__disconnect-dialog .components-modal__content > div:not(.components-modal__header) {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
height: 100%;
|
|
13
|
+
}
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/jetpack-connection",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.37.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,11 +14,11 @@
|
|
|
14
14
|
"author": "Automattic",
|
|
15
15
|
"license": "GPL-2.0-or-later",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@automattic/jetpack-analytics": "^0.1.
|
|
18
|
-
"@automattic/jetpack-api": "^0.
|
|
19
|
-
"@automattic/jetpack-components": "^0.67.
|
|
20
|
-
"@automattic/jetpack-config": "^0.1.
|
|
21
|
-
"@automattic/jetpack-script-data": "^0.2.
|
|
17
|
+
"@automattic/jetpack-analytics": "^0.1.36",
|
|
18
|
+
"@automattic/jetpack-api": "^0.19.0",
|
|
19
|
+
"@automattic/jetpack-components": "^0.67.1",
|
|
20
|
+
"@automattic/jetpack-config": "^0.1.29",
|
|
21
|
+
"@automattic/jetpack-script-data": "^0.2.1",
|
|
22
22
|
"@wordpress/base-styles": "5.17.0",
|
|
23
23
|
"@wordpress/browserslist-config": "6.17.0",
|
|
24
24
|
"@wordpress/components": "29.3.0",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"prop-types": "^15.7.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@automattic/jetpack-base-styles": "^0.6.
|
|
34
|
+
"@automattic/jetpack-base-styles": "^0.6.43",
|
|
35
35
|
"@babel/core": "7.26.0",
|
|
36
36
|
"@babel/preset-react": "7.26.3",
|
|
37
|
-
"@storybook/addon-actions": "8.
|
|
37
|
+
"@storybook/addon-actions": "8.5.8",
|
|
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",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"jest-environment-jsdom": "29.7.0",
|
|
44
44
|
"react": "18.3.1",
|
|
45
45
|
"react-dom": "18.3.1",
|
|
46
|
-
"storybook": "8.
|
|
46
|
+
"storybook": "8.5.8"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"react": "^18.0.0",
|