idc-notice.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /* global idcL10n, jQuery, analytics, history, wpCookies */
  2. ( function( $ ) {
  3. var restNonce = idcL10n.nonce,
  4. currentUrl = idcL10n.currentUrl,
  5. restRoot = idcL10n.apiRoot,
  6. notice = $( '.jp-idc-notice' ),
  7. idcButtons = $( '.jp-idc-notice .dops-button' ),
  8. tracksUser = idcL10n.tracksUserData,
  9. tracksEvent = idcL10n.tracksEventData,
  10. adminBarMenu = $( '#wp-admin-bar-jetpack-idc' ),
  11. confirmSafeModeButton = $( '#jp-idc-confirm-safe-mode-action' ),
  12. fixConnectionButton = $( '#jp-idc-fix-connection-action' ),
  13. migrateButton = $( '#jp-idc-migrate-action'),
  14. reconnectButton = $( '#jp-idc-reconnect-site-action' ),
  15. errorNotice = $( '.jp-idc-error__notice'),
  16. erroredAction = false;
  17. // Initialize Tracks and bump stats.
  18. if ( 'undefined' !== typeof analytics ) {
  19. analytics.initialize( tracksUser.userid, tracksUser.username );
  20. }
  21. if ( tracksEvent.isAdmin ) {
  22. trackAndBumpMCStats( 'notice_view' );
  23. } else {
  24. trackAndBumpMCStats( 'non_admin_notice_view', { 'page': tracksEvent.currentScreen } );
  25. }
  26. clearConfirmationArgsFromUrl();
  27. // If the user dismisses the notice, set a cookie for one week so we don't display it for that time.
  28. notice.on( 'click', '.notice-dismiss', function() {
  29. var secure = ( 'https:' === window.location.protocol );
  30. wpCookies.set( 'jetpack_idc_dismiss_notice', '1', 7 * 24 * 60 * 60, false, false, secure );
  31. trackAndBumpMCStats( 'non_admin_notice_dismiss', { 'page': tracksEvent.currentScreen } );
  32. } );
  33. notice.on( 'click', '#jp-idc-error__action', function() {
  34. errorNotice.hide();
  35. switch( erroredAction ) {
  36. case 'confirm':
  37. confirmSafeMode();
  38. break;
  39. case 'start-fresh':
  40. startFreshConnection();
  41. break;
  42. case 'migrate':
  43. migrateStatsAndSubscribers();
  44. break;
  45. default:
  46. return;
  47. }
  48. } );
  49. // Confirm Safe Mode
  50. confirmSafeModeButton.on( 'click', confirmSafeMode );
  51. // Fix connection
  52. fixConnectionButton.on( 'click', fixJetpackConnection );
  53. // Start fresh connection
  54. reconnectButton.on( 'click', startFreshConnection );
  55. // Starts migration process.
  56. migrateButton.on( 'click', migrateStatsAndSubscribers );
  57. function disableDopsButtons() {
  58. idcButtons.prop( 'disabled', true );
  59. }
  60. function enableDopsButtons() {
  61. idcButtons.prop( 'disabled', false );
  62. }
  63. function clearConfirmationArgsFromUrl( allowReload ) {
  64. allowReload = 'undefined' === typeof allowReload ? false : allowReload;
  65. // If the jetpack_idc_clear_confirmation query arg is present, let's try to clear it.
  66. //
  67. // Otherwise, there's a weird flow where if the user dismisses the notice, then shows the notice, then clicks
  68. // the confirm safe mode button again, and then reloads the page, then the notice never disappears.
  69. if ( window.location.search && -1 !== window.location.search.indexOf( 'jetpack_idc_clear_confirmation' ) ) {
  70. trackAndBumpMCStats( 'clear_confirmation_clicked' );
  71. // If push state is available, let's use that to minimize reloading the page.
  72. // Otherwise, we can clear the args by reloading the page.
  73. if ( history && history.pushState ) {
  74. history.pushState( {}, '', currentUrl );
  75. } else if ( allowReload ) {
  76. window.location.href = currentUrl;
  77. }
  78. }
  79. }
  80. function confirmSafeMode() {
  81. errorNotice.hide();
  82. trackAndBumpMCStats( 'confirm_safe_mode' );
  83. var route = restRoot + 'jetpack/v4/identity-crisis/confirm-safe-mode';
  84. disableDopsButtons();
  85. $.ajax( {
  86. method: 'POST',
  87. beforeSend : function ( xhr ) {
  88. xhr.setRequestHeader( 'X-WP-Nonce', restNonce );
  89. },
  90. url: route,
  91. data: {},
  92. success: function() {
  93. notice.hide();
  94. adminBarMenu.removeClass( 'hide' );
  95. // We must refresh the Jetpack admin UI page in order for the React UI to render.
  96. if ( window.location.search && 1 === window.location.search.indexOf( 'page=jetpack' ) ) {
  97. window.location.reload();
  98. }
  99. },
  100. error: function( error ) {
  101. erroredAction = 'confirm';
  102. displayErrorNotice( error );
  103. enableDopsButtons();
  104. }
  105. } );
  106. }
  107. function migrateStatsAndSubscribers() {
  108. errorNotice.hide();
  109. trackAndBumpMCStats( 'migrate' );
  110. var route = restRoot + 'jetpack/v4/identity-crisis/migrate';
  111. disableDopsButtons();
  112. $.ajax( {
  113. method: 'POST',
  114. beforeSend : function ( xhr ) {
  115. xhr.setRequestHeader( 'X-WP-Nonce', restNonce );
  116. },
  117. url: route,
  118. data: {},
  119. success: function() {
  120. notice.hide();
  121. if ( $( 'body' ).hasClass( 'toplevel_page_jetpack' ) ) {
  122. // On the main Jetpack page, sites in IDC will not see Jetpack's interface.
  123. // Once IDC is resolved, we need to refresh the page to regain access to the UI.
  124. window.location.reload( true );
  125. }
  126. },
  127. error: function( error ) {
  128. erroredAction = 'migrate';
  129. displayErrorNotice( error );
  130. enableDopsButtons();
  131. }
  132. } );
  133. }
  134. function fixJetpackConnection() {
  135. errorNotice.hide();
  136. trackAndBumpMCStats( 'fix_connection' );
  137. notice.addClass( 'jp-idc-show-second-step' );
  138. }
  139. /**
  140. * On successful request of the endpoint, we will redirect to the
  141. * connection auth flow after appending a specific 'from=' param for tracking.
  142. */
  143. function startFreshConnection() {
  144. errorNotice.hide();
  145. trackAndBumpMCStats( 'start_fresh' );
  146. var route = restRoot + 'jetpack/v4/identity-crisis/start-fresh';
  147. disableDopsButtons();
  148. $.ajax( {
  149. method: 'POST',
  150. beforeSend : function ( xhr ) {
  151. xhr.setRequestHeader( 'X-WP-Nonce', restNonce );
  152. },
  153. url: route,
  154. data: {},
  155. success: function( connectUrl ){
  156. // Add a from param and take them to connect.
  157. window.location = connectUrl + '&from=idc-notice';
  158. },
  159. error: function( error ) {
  160. erroredAction = 'start-fresh';
  161. displayErrorNotice( error );
  162. enableDopsButtons();
  163. }
  164. } );
  165. }
  166. /**
  167. * Displays an error message from the REST endpoints we're hitting.
  168. *
  169. * @param error {Object} Object containing the errored response from the API
  170. */
  171. function displayErrorNotice( error ) {
  172. var errorDescription = $( '.jp-idc-error__desc' );
  173. if ( error && error.responseJSON && error.responseJSON.message ) {
  174. errorDescription.html( error.responseJSON.message );
  175. } else {
  176. errorDescription.html( '' );
  177. }
  178. errorNotice.css( 'display', 'flex' );
  179. }
  180. /**
  181. * This function will fire both a Tracks and MC stat.
  182. * It will make sure to format the event name properly for the given stat home.
  183. *
  184. * Tracks: Will be prefixed by 'jetpack_idc_' and use underscores.
  185. * MC: Will not be prefixed, and will use dashes.
  186. *
  187. * @param eventName string
  188. * @param extraProps object
  189. */
  190. function trackAndBumpMCStats( eventName, extraProps ) {
  191. if ( 'undefined' === typeof extraProps || 'object' !== typeof extraProps ) {
  192. extraProps = {};
  193. }
  194. if ( eventName && eventName.length && 'undefined' !== typeof analytics && analytics.tracks && analytics.mc ) {
  195. // Format for Tracks
  196. eventName = eventName.replace( /-/g, '_' );
  197. eventName = eventName.indexOf( 'jetpack_idc_' ) !== 0 ? 'jetpack_idc_' + eventName : eventName;
  198. analytics.tracks.recordEvent( eventName, extraProps );
  199. // Now format for MC stats
  200. eventName = eventName.replace( 'jetpack_idc_', '' );
  201. eventName = eventName.replace( /_/g, '-' );
  202. analytics.mc.bumpStat( 'jetpack-idc', eventName );
  203. }
  204. }
  205. })( jQuery );