dashboardView.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /**
  2. * Dashboard Layout View
  3. *
  4. * @package Ninja Forms
  5. * @subpackage Dashboard
  6. * @copyright (c) 2017 WP Ninjas
  7. * @since 3.2
  8. */
  9. define( [ 'views/sections/widgets.js', 'views/sections/services.js', 'views/sections/apps.js', 'views/sections/memberships.js', 'views/oauth.js', 'views/promotion.js' ], function( WidgetView, ServicesView, AppsView, MembershipsView, OAuthView, PromotionView ) {
  10. var view = Marionette.View.extend( {
  11. template: "#tmpl-nf-dashboard",
  12. currentView: 'widgets',
  13. regions: {
  14. notices: '.notices',
  15. promotions: '.promotions',
  16. content: '.content'
  17. },
  18. events: {
  19. 'click .widgets a': function(e){
  20. this.showChildView( 'content', new WidgetView() );
  21. jQuery( '.' + this.currentView).find( 'a' ).removeClass( 'active' );
  22. e.target.classList.add( 'active' );
  23. this.currentView = 'widgets';
  24. },
  25. 'click .services a': function(e){
  26. this.showChildView( 'content', new ServicesView() );
  27. jQuery( '.' + this.currentView).find( 'a' ).removeClass( 'active' );
  28. e.target.classList.add( 'active' );
  29. this.currentView = 'services';
  30. },
  31. 'click .apps a': function(e){
  32. this.showChildView( 'content', new AppsView() );
  33. jQuery( '.' + this.currentView).find( 'a' ).removeClass( 'active' );
  34. e.target.classList.add( 'active' );
  35. this.currentView = 'apps';
  36. },
  37. 'click .memberships a': function(e){
  38. this.showChildView( 'content', new MembershipsView() );
  39. jQuery( '.' + this.currentView).find( 'a' ).removeClass( 'active' );
  40. e.target.classList.add( 'active' );
  41. this.currentView = 'memberships';
  42. },
  43. },
  44. initialize: function() {
  45. switch( window.location.hash ) {
  46. case '#apps':
  47. this.currentView = 'apps';
  48. break;
  49. case '#services':
  50. this.currentView = 'services';
  51. break;
  52. case '#memberships':
  53. this.currentView = 'memberships';
  54. break;
  55. case '#widgets':
  56. default:
  57. this.currentView = 'widgets';
  58. }
  59. /**
  60. * Radio Routers
  61. * TODO: Clean this up.
  62. */
  63. nfRadio.channel( 'dashboard' ).reply( 'show:widgets', function(){
  64. this.showChildView('content', new WidgetView() );
  65. jQuery( 'nav.sections a.active' ).removeClass( 'active' );
  66. jQuery( 'nav.sections .widgets a' ).addClass( 'active' );
  67. this.currentView = 'widgets';
  68. }, this );
  69. nfRadio.channel( 'dashboard' ).reply( 'show:services', function(){
  70. this.showChildView('content', new ServicesView() );
  71. jQuery( 'nav.sections a.active' ).removeClass( 'active' );
  72. jQuery( 'nav.sections .services a' ).addClass( 'active' );
  73. this.currentView = 'services';
  74. }, this );
  75. nfRadio.channel( 'dashboard' ).reply( 'show:apps', function(){
  76. this.showChildView('content', new AppsView() );
  77. jQuery( 'nav.sections a.active' ).removeClass( 'active' );
  78. jQuery( 'nav.sections .apps a' ).addClass( 'active' );
  79. this.currentView = 'apps';
  80. }, this );
  81. },
  82. onRender: function() {
  83. if( useServices ) this.showChildView( 'notices', new OAuthView() );
  84. if( useServices ) this.showChildView( 'promotions', new PromotionView() );
  85. switch( window.location.hash ) {
  86. case '#apps':
  87. var childView = new AppsView();
  88. break;
  89. case '#memberships':
  90. var childView = new MembershipsView();
  91. break;
  92. case '#services':
  93. var childView = new ServicesView();
  94. break;
  95. case '#widgets':
  96. default:
  97. var childView = new WidgetView();
  98. }
  99. this.showChildView('content', childView );
  100. // If the user has not seen the opt-in modal yet...
  101. if ( '1' == nfAdmin.showOptin ) {
  102. // Declare all of our opt-in code here.
  103. var optinModal = new jBox( 'Modal', {
  104. closeOnEsc: false,
  105. closeOnClick: false,
  106. width: 400
  107. } );
  108. // Define the modal title.
  109. var title = document.createElement( 'div' );
  110. title.id = 'optin-modal-title';
  111. var titleStyling = document.createElement( 'h2' );
  112. titleStyling.innerHTML = 'Help make Ninja Forms better!';
  113. title.appendChild( titleStyling );
  114. // Define the modal content.
  115. var content = document.createElement( 'div' );
  116. content.classList.add( 'message' );
  117. content.style.padding = '0px 20px 20px 20px';
  118. content.innerHTML = nfi18n.optinContent;
  119. var p = document.createElement( 'p' );
  120. p.style.paddingBottom = '10px';
  121. var checkBox = document.createElement( 'input' );
  122. checkBox.id = 'optin-send-email';
  123. checkBox.setAttribute( 'type', 'checkbox' );
  124. checkBox.style.margin = '7px';
  125. var label = document.createElement( 'label' );
  126. label.setAttribute( 'for', 'optin-send-email' );
  127. label.innerHTML = nfi18n.optinYesplease;
  128. p.appendChild( checkBox );
  129. p.appendChild( label );
  130. content.appendChild( p );
  131. p = document.createElement( 'p' );
  132. p.id = 'optin-block';
  133. p.style.padding = '0px 5px 20px 5px';
  134. p.style.display = 'none';
  135. var email = document.createElement( 'input' );
  136. email.id = 'optin-email-address';
  137. email.setAttribute( 'type', 'text' );
  138. email.setAttribute( 'value', nfAdmin.currentUserEmail );
  139. email.style.width = '100%';
  140. email.style.fontSize = '16px';
  141. p.appendChild( email );
  142. content.appendChild( p );
  143. var spinner = document.createElement( 'span' );
  144. spinner.id = 'optin-spinner';
  145. spinner.classList.add( 'spinner' );
  146. spinner.style.display = 'none';
  147. content.appendChild( spinner );
  148. var actions = document.createElement( 'div' );
  149. actions.id = 'optin-buttons';
  150. actions.classList.add( 'buttons' );
  151. var cancel = document.createElement( 'div' );
  152. cancel.id = 'optout';
  153. cancel.classList.add( 'nf-button', 'secondary' );
  154. cancel.innerHTML = nfi18n.optinSecondary;
  155. actions.appendChild( cancel );
  156. var confirm = document.createElement( 'div' );
  157. confirm.id = 'optin';
  158. confirm.classList.add( 'nf-button', 'primary', 'pull-right' );
  159. confirm.innerHTML = nfi18n.optinPrimary;
  160. actions.appendChild( confirm );
  161. content.appendChild( actions );
  162. // Define the success title.
  163. var successTitle = document.createElement( 'h2' );
  164. successTitle.innerHTML = nfi18n.optinAwesome;
  165. // Define the success content.
  166. var successContent = document.createElement( 'div' );
  167. successContent.id = 'optin-thankyou';
  168. successContent.classList.add( 'message' );
  169. successContent.style.padding = '20px';
  170. successContent.innerHTML = nfi18n.optinThanks;
  171. // Set the options for the modal and open it.
  172. optinModal.setContent( document.createElement( 'div' ).appendChild( content ).innerHTML );
  173. optinModal.setTitle( document.createElement( 'div' ).appendChild( title ).innerHTML );
  174. optinModal.open();
  175. // Show/Hide email field, based on the opt-in checkbox.
  176. jQuery( '#optin-send-email' ).click( function( e ) {
  177. if( jQuery( this ).is( ':checked' ) ) {
  178. jQuery( '#optin-block' ).show();
  179. } else {
  180. jQuery( '#optin-block' ).hide();
  181. }
  182. } );
  183. // Setup the optin click event.
  184. jQuery( '#optin' ).click( function( e ) {
  185. var sendEmail;
  186. if ( jQuery( '#optin-send-email' ).attr( 'checked' ) ) {
  187. sendEmail = 1;
  188. userEmail = jQuery( '#optin-email-address' ).val();
  189. } else {
  190. sendEmail = 0;
  191. userEmail = '';
  192. }
  193. // Disable our buttons.
  194. jQuery( '#optin' ).unbind( 'click' );
  195. jQuery( '#optout' ).unbind( 'click' );
  196. // Get a reference to the current width (to avoid resizing the button).
  197. var width = jQuery( '#optin' ).width();
  198. // Show spinner.
  199. jQuery( '#optin' ).html( '<span class="dashicons dashicons-update dashicons-update-spin"></span>' );
  200. jQuery( '#optin' ).width( width );
  201. // Hit AJAX endpoint and opt-in.
  202. jQuery.post( ajaxurl, { action: 'nf_optin', ninja_forms_opt_in: 1, send_email: sendEmail, user_email: userEmail },
  203. function( response ) {
  204. /**
  205. * When we get a response from our endpoint, show a thank you and set a timeout
  206. * to close the modal.
  207. */
  208. optinModal.setTitle( document.createElement( 'div' ).appendChild( successTitle ).innerHTML );
  209. optinModal.setContent( document.createElement( 'div' ).appendChild( successContent ).innerHTML );
  210. setTimeout (
  211. function(){
  212. optinModal.close();
  213. },
  214. 2000
  215. );
  216. } );
  217. } );
  218. // Setup the optout click event.
  219. jQuery( '#optout' ).click( function( e ) {
  220. // Disable our buttons.
  221. jQuery( '#optin' ).unbind( 'click' );
  222. jQuery( '#optout' ).unbind( 'click' );
  223. // Get a reference to the current width (to avoid resizing the button).
  224. var width = jQuery( '#optout' ).width();
  225. // Show spinner.
  226. jQuery( '#optout' ).html( '<span class="dashicons dashicons-update dashicons-update-spin"></span>' );
  227. jQuery( '#optout' ).width( width );
  228. // Hit AJAX endpoint and opt-in.
  229. jQuery.post( ajaxurl, { action: 'nf_optin', ninja_forms_opt_in: 0 }, function( response ) {
  230. // When we get a response from our endpoint, close the modal.
  231. optinModal.close();
  232. } );
  233. } );
  234. } // If we've been told to run cleanup...
  235. else if ( '1' == nfAdmin.doingCleanup ) {
  236. // Get the context for later.
  237. var that = this;
  238. // Define our modal options.
  239. var modalData = {
  240. width: 450,
  241. closeOnClick: false,
  242. closeOnEsc: false,
  243. content: nfi18n.cleanupContent,
  244. useProgressBar: true,
  245. loadingText: nfi18n.cleanupLoading,
  246. btnSecondary: {
  247. text: nfi18n.cleanupSecondary,
  248. callback: function() {
  249. cleanupModal.toggleModal( false );
  250. }
  251. },
  252. btnPrimary: {
  253. text: nfi18n.cleanupPrimary,
  254. callback: function() {
  255. // Prevent the user from leaving without firing an alert.
  256. jQuery( window ).bind( 'beforeunload', function() {
  257. return 'Are you sure? Leaving before the process completes could cause damage to your data.';
  258. } );
  259. // Hide the buttons.
  260. cleanupModal.maybeShowActions( false );
  261. // Show the progress bar.
  262. cleanupModal.maybeShowProgress( true );
  263. // Begin our cleanup process.
  264. that.cleanupProcess( that, -1, cleanupModal );
  265. },
  266. },
  267. };
  268. // Setup our modal.
  269. var cleanupModal = new NinjaModal( modalData );
  270. }
  271. // If form telemetry is defined...
  272. // AND if we should run it...
  273. if ( 'undefined' !== typeof nfAdmin.formTelemetry && 1 == nfAdmin.formTelemetry ) {
  274. // Make our AJAX call.
  275. var data = {
  276. action: 'nf_form_telemetry',
  277. security: nfAdmin.ajaxNonce
  278. }
  279. // Make our AJAX call.
  280. jQuery.post( ajaxurl, data );
  281. }
  282. },
  283. templateContext: function() {
  284. var that = this;
  285. return {
  286. renderNav: function() {
  287. var content = document.createElement( 'div' );
  288. _.each( nfDashItems, function(section) {
  289. var item = document.createElement( 'li' );
  290. var link = document.createElement( 'a' );
  291. link.href = '#' + section.slug;
  292. if ( that.currentView == section.slug ) link.classList.add( 'active' );
  293. link.innerHTML = section.niceName;
  294. item.classList.add( section.slug );
  295. item.appendChild( link );
  296. content.appendChild( item );
  297. } );
  298. return content.innerHTML;
  299. },
  300. }
  301. },
  302. /**
  303. * Function to manage our data cleanup batch process response.
  304. *
  305. * @since 3.3.1
  306. *
  307. * @param context (this) The context at the time of function definition.
  308. * @param steps (int) The total number of steps in this process.
  309. * @param modal (jBox) A reference to the modal where this process is running.
  310. */
  311. cleanupProcess: function( context, steps, modal ) {
  312. var data = {
  313. action: 'nf_batch_process',
  314. batch_type: 'data_cleanup',
  315. security: nfAdmin.batchNonce
  316. };
  317. jQuery.post( ajaxurl, data, function( response ) {
  318. response = JSON.parse( response );
  319. // If we're done...
  320. if ( response.batch_complete ) {
  321. // Push our progress bar to 100%.
  322. modal.setProgress( 100 );
  323. // Allow the user to leave the page now.
  324. jQuery( window ).unbind( 'beforeunload' );
  325. modal.toggleModal( false );
  326. // Exit.
  327. return false;
  328. }
  329. // If we do not yet have a determined number of steps...
  330. if ( -1 == steps ) {
  331. // If step_toal is defined...
  332. if ( 'undefined' != typeof response.step_total ) {
  333. // Use the step_total.
  334. steps = response.step_total;
  335. } // Otherwise... (step_total is not defined)
  336. else {
  337. // Use step_remaining.
  338. steps = response.step_remaining;
  339. }
  340. }
  341. // Calculate our current step.
  342. var step = steps - response.step_remaining;
  343. // Calculate our maximum progress for this step.
  344. var maxProgress = Math.round( step / steps * 100 );
  345. // Increment the progress.
  346. modal.incrementProgress ( maxProgress );
  347. // Recall our function...
  348. context.cleanupProcess( context, steps, modal );
  349. } );
  350. }
  351. } );
  352. return view;
  353. } );