diff --git a/classes/Visualizer/Module/Setup.php b/classes/Visualizer/Module/Setup.php index 8a56055eb..f0cc81f47 100644 --- a/classes/Visualizer/Module/Setup.php +++ b/classes/Visualizer/Module/Setup.php @@ -252,10 +252,21 @@ public function adminInit() { // fire any upgrades necessary. Visualizer_Module_Upgrade::upgrade(); - if ( get_option( 'visualizer-activated' ) ) { + $activated_flag = get_option( 'visualizer-activated' ); + $fresh_install = get_option( 'visualizer_fresh_install', false ); + $is_pro = Visualizer_Module::is_pro(); + if ( $activated_flag ) { + if ( function_exists( 'wp_doing_ajax' ) && wp_doing_ajax() ) { + // Defer redirect until a normal admin request. + return; + } + if ( wp_doing_cron() ) { + // Defer redirect during cron requests. + return; + } delete_option( 'visualizer-activated' ); if ( ! headers_sent() ) { - if ( ! Visualizer_Module::is_pro() && ! empty( get_option( 'visualizer_fresh_install', false ) ) ) { + if ( ! $is_pro && ! empty( $fresh_install ) ) { $redirect_url = array( 'page' => 'visualizer-setup-wizard', 'tab' => '#step-1', diff --git a/classes/Visualizer/Module/Wizard.php b/classes/Visualizer/Module/Wizard.php index d2f6290bf..9c639170e 100644 --- a/classes/Visualizer/Module/Wizard.php +++ b/classes/Visualizer/Module/Wizard.php @@ -73,6 +73,7 @@ public function registerAdminMenu() { } } + /** * Method to register the setup wizard page. * @@ -168,7 +169,7 @@ public function dismissWizard( $redirect_to_dashboard = true ) { */ public function visualizer_wizard_step_process() { check_ajax_referer( VISUALIZER_ABSPATH, 'security' ); - $step = ! empty( $_POST['step'] ) ? filter_input( INPUT_POST, 'step', FILTER_SANITIZE_STRING ) : 1; + $step = ! empty( $_POST['step'] ) ? sanitize_text_field( wp_unslash( $_POST['step'] ) ) : 1; switch ( $step ) { case 'step_2': $this->setup_wizard_import_chart(); @@ -193,7 +194,7 @@ public function visualizer_wizard_step_process() { */ private function setup_wizard_import_chart() { // phpcs:ignore WordPress.Security.NonceVerification.Missing - $chart_type = ! empty( $_POST['chart_type'] ) ? filter_input( INPUT_POST, 'chart_type', FILTER_SANITIZE_STRING ) : ''; + $chart_type = ! empty( $_POST['chart_type'] ) ? sanitize_text_field( wp_unslash( $_POST['chart_type'] ) ) : ''; $chart_status = Visualizer_Module_Admin::checkChartStatus( $chart_type ); if ( ! $chart_status ) { wp_send_json( @@ -386,7 +387,8 @@ private function setup_wizard_import_chart() { ); $this->update_wizard_data( $wizard_data, false ); $response = array( - 'success' => 1, + 'success' => 1, + 'chart_id' => $chart_id, ); } wp_send_json( $response ); @@ -416,7 +418,7 @@ private function update_wizard_data( $data = array(), $merge_option = true ) { private function setup_wizard_create_draft_page( $return_page_id = false ) { $add_basic_shortcode = ! empty( $_POST['add_basic_shortcode'] ) ? sanitize_text_field( wp_unslash( $_POST['add_basic_shortcode'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing $add_basic_shortcode = 'true' === $add_basic_shortcode ? true : false; - $basic_shortcode = ! empty( $_POST['basic_shortcode'] ) ? filter_input( INPUT_POST, 'basic_shortcode', FILTER_SANITIZE_STRING ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing + $basic_shortcode = ! empty( $_POST['basic_shortcode'] ) ? sanitize_text_field( wp_unslash( $_POST['basic_shortcode'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing if ( ! $add_basic_shortcode ) { wp_send_json( @@ -476,7 +478,7 @@ private function setup_wizard_create_draft_page( $return_page_id = false ) { */ private function setup_wizard_install_plugin() { // phpcs:ignore WordPress.Security.NonceVerification.Missing - $slug = ! empty( $_POST['slug'] ) ? filter_input( INPUT_POST, 'slug', FILTER_SANITIZE_STRING ) : ''; + $slug = ! empty( $_POST['slug'] ) ? sanitize_text_field( wp_unslash( $_POST['slug'] ) ) : ''; if ( empty( $slug ) ) { wp_send_json( array( @@ -496,8 +498,10 @@ private function setup_wizard_install_plugin() { } if ( ! empty( $slug ) ) { + $wizard_data = get_option( self::OPTION_NAME, array() ); require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; include_once ABSPATH . 'wp-admin/includes/plugin-install.php'; + require_once ABSPATH . 'wp-admin/includes/plugin.php'; $api = plugins_api( 'plugin_information', @@ -559,11 +563,33 @@ private function setup_wizard_install_plugin() { wp_send_json( $status ); } - activate_plugin( 'optimole-wp/optimole-wp.php' ); - delete_transient( 'optml_fresh_install' ); - // Update wizard data. - $wizard_data['enable_perfomance'] = true; - $this->update_wizard_data( $wizard_data ); + $installed_plugins = get_plugins( '/' . sanitize_key( wp_unslash( $slug ) ) ); + if ( ! empty( $installed_plugins ) ) { + $plugin_files = array_keys( $installed_plugins ); + $plugin_file = sanitize_key( wp_unslash( $slug ) ) . '/' . $plugin_files[0]; + activate_plugin( $plugin_file ); + } + $wizard_data_updated = false; + if ( 'optimole-wp' === $slug ) { + delete_transient( 'optml_fresh_install' ); + // Update wizard data. + $wizard_data['enable_perfomance'] = true; + $wizard_data_updated = true; + } + if ( 'otter-blocks' === $slug ) { + // Update wizard data. + $wizard_data['enable_otter_blocks'] = true; + $wizard_data_updated = true; + update_option( 'themeisle_blocks_settings_onboarding', false ); + } + if ( 'wp-cloudflare-page-cache' === $slug ) { + // Update wizard data. + $wizard_data['enable_page_cache'] = true; + $wizard_data_updated = true; + } + if ( $wizard_data_updated ) { + $this->update_wizard_data( $wizard_data ); + } wp_send_json( array( diff --git a/css/style-wizard.css b/css/style-wizard.css index 0cbd2660c..c157f7624 100644 --- a/css/style-wizard.css +++ b/css/style-wizard.css @@ -244,6 +244,13 @@ input.vz-switch-toggle[type=checkbox]:checked:before{ position: relative; border-bottom: 1px solid #D9D9D9; } +.vz-form-wrap .form-block.no-sep{ + border-bottom: 0; + padding-bottom: 12px; +} +.vz-form-wrap .form-block.vz-final-block{ + padding: 12px 0; +} .vz-form-wrap .form-block:last-child{ border-bottom: 0; } @@ -948,6 +955,21 @@ display: none; padding-left: 20px; padding-right: 20px; } +.vz-accordion-title--static{ + padding: 22px 30px 22px 80px; +} +.vz-accordion-title--static .vz-checkbox{ + position: absolute; + left: 30px; + top: 50%; + margin-top: -10px; + width: 20px; + height: 20px; + z-index: 12; +} +.vz-accordion-content--static{ + display: block; +} .vz-features-list ul li{ padding: 25px 0; @@ -968,6 +990,136 @@ display: none; .vz-features-list ul li .txt{ width: 100%; } +.vz-final-options{ + display: flex; + flex-direction: column; + gap: 10px; +} +.vz-option-card{ + display: flex; + align-items: center; + gap: 16px; + padding: 16px 18px; + border: 1px solid #E5E7EB; + border-radius: 8px; + background: #fff; + position: relative; +} +.vz-option-check{ + width: 20px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} +.vz-option-check input[type=checkbox]{ + width: 18px; + height: 18px; +} +.vz-option-icon{ + width: 40px; + height: 40px; + border-radius: 8px; + background: #F3F4F6; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} +.vz-option-icon img{ + display: block; + max-width: 24px; + max-height: 24px; +} +.vz-option-body{ + flex: 1; +} +.vz-option-title{ + font-size: 16px; + font-weight: 600; + color: #0f172a; + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 4px; +} +.vz-option-title .pro-label.free-label{ + font-size: 11px; + line-height: 14px; + padding: 2px 8px 3px; +} +.vz-option-card--newsletter .vz-option-icon{ + background: #E6F3F3; + color: #39C3D2; +} +.vz-option-card--newsletter .vz-option-icon .dashicons{ + font-size: 22px; + width: 22px; + height: 22px; +} +.vz-option-card--newsletter .vz-option-body{ + display: flex; + flex-direction: column; + gap: 6px; +} +.vz-option-card--newsletter .vz-option-input{ + max-width: 320px; + display: flex; + align-items: center; + gap: 8px; +} +.vz-option-card--newsletter .vz-change-email{ + background: transparent; + border: 0; + color: #39C3D2; + text-decoration: underline; + cursor: pointer; + padding: 0 0 0 6px; + font-size: 13px; +} +.vz-option-card--newsletter .vz-email-text{ + color: #39C3D2; + font-weight: 600; + padding-left: 6px; +} +.vz-install-status{ + position: absolute; + right: 14px; + top: 14px; + width: 18px; + height: 18px; + border-radius: 50%; + border: 2px solid #cbd5e1; + display: none; + align-items: center; + justify-content: center; + font-size: 12px; + line-height: 1; + color: #ffffff; +} +.vz-install-status.is-installing{ + display: flex; + border-color: #39C3D2; + border-top-color: transparent; + animation: spin 1s linear infinite; +} +.vz-install-status.is-done{ + display: flex; + background: #00AA63; + border-color: #00AA63; +} +.vz-install-status.is-error{ + display: flex; + background: #d63638; + border-color: #d63638; +} +.vz-install-status.is-done:before{ + content: "✓"; +} +.vz-install-status.is-error:before{ + content: "!"; +} .pro-label{ background: #007CBA; border-radius: 6px; @@ -988,34 +1140,23 @@ display: none; } /* visualizer accordion style End */ .vz-chart-list{ -/* max-width: 780px;*/ - padding: 0 18px; + max-width: 1100px; + padding: 0; margin-bottom: 40px; + margin-left: auto; + margin-right: auto; } .vz-chart-list > ul{ - display: flex; - flex-wrap: wrap; - justify-content: space-between; + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + gap: 16px; + align-items: stretch; } .vz-chart-list .slick-arrow{ - position: absolute; - width: 30px; - top: 50%; - height: 30px; - margin-top: -15px; - font-size: 0; - color: #757575; - display: grid; - place-items: center; - border: 0; - background: transparent; - cursor: pointer; + display: none; } .vz-chart-list .slick-arrow:before{ - display: block; - font-family: "dashicons"; - font-size: 24px; - line-height: 1; + display: none; } .vz-chart-list .slick-arrow.slick-prev{ left: -42px; @@ -1030,19 +1171,19 @@ display: none; content: "\f345"; } .vz-chart-list > ul > li{ - width: 48%; - max-width: 362px; - padding-bottom: 60px; + width: 100%; + max-width: 100%; + padding-bottom: 0; } .vz-chart-list .slick-slide{ - margin-right: 34px; + margin-right: 0; } .vz-chart-option{ - width: 317px; + width: 100%; position: relative; display: flex; flex-wrap: wrap; - padding: 12px 12px 20px; + padding: 12px 12px 16px; } .vz-chart-option .img{ order: 1; @@ -1050,8 +1191,9 @@ display: none; z-index: 1; display: block; width: 100%; - max-width: 338px; - height: 198px; + max-width: 100%; + aspect-ratio: 23 / 18; + height: auto; background-color: #ffffff; margin-bottom: 20px; background-image: url(../images/chart_types_v395.png); @@ -1060,23 +1202,54 @@ display: none; transition: all .3s ease-in-out; /* filter: grayscale(100%); -webkit-filter: grayscale(100%); */ - background-size: 900px 1150px; + --wizard-sprite-scale: 0.45; + background-size: calc(900px * var(--wizard-sprite-scale)) calc(1150px * var(--wizard-sprite-scale)); filter: grayscale(100%); } .vz-chart-option .img.type-box-pie{ - background-position: -5px -17px; + background-position: calc(-5px * var(--wizard-sprite-scale)) calc(-17px * var(--wizard-sprite-scale)); } .vz-chart-option .img.type-box-bar{ - background-position: -305px -235px; + background-position: calc(-305px * var(--wizard-sprite-scale)) calc(-235px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-area{ + background-position: calc(-8px * var(--wizard-sprite-scale)) calc(-225px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-scatter{ + background-position: calc(-300px * var(--wizard-sprite-scale)) calc(0px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-gauge{ + background-position: calc(-7px * var(--wizard-sprite-scale)) calc(-450px * var(--wizard-sprite-scale)); } .vz-chart-option .img.type-box-line{ - background-position: -606px -14px; + background-position: calc(-606px * var(--wizard-sprite-scale)) calc(-14px * var(--wizard-sprite-scale)); } .vz-chart-option .img.type-box-tabular{ - background-position: -306px -693px; + background-position: calc(-306px * var(--wizard-sprite-scale)) calc(-693px * var(--wizard-sprite-scale)); } .vz-chart-option .img.type-box-geo{ - background-position: -603px -459px; + background-position: calc(-603px * var(--wizard-sprite-scale)) calc(-459px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-candlestick{ + background-position: calc(-304px * var(--wizard-sprite-scale)) calc(-450px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-bubble{ + background-position: calc(-604px * var(--wizard-sprite-scale)) calc(-906px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-column{ + background-position: calc(-600px * var(--wizard-sprite-scale)) calc(-225px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-timeline{ + background-position: calc(-8px * var(--wizard-sprite-scale)) calc(-670px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-combo{ + background-position: calc(-606px * var(--wizard-sprite-scale)) calc(-670px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-polarArea{ + background-position: calc(-2px * var(--wizard-sprite-scale)) calc(-912px * var(--wizard-sprite-scale)); +} +.vz-chart-option .img.type-box-radar{ + background-position: calc(-301px * var(--wizard-sprite-scale)) calc(-899px * var(--wizard-sprite-scale)); } .vz-chart-option:hover .img{ background-image: url(../images/chart_types_v395.png); @@ -1112,24 +1285,34 @@ display: none; display: flex; flex-wrap: wrap; align-items: center; + font-size: 13px; + line-height: 16px; } .vz-pro-label-wrap { order: 3; width: calc(100% - 20px); padding-left: 12px; - position: relative; z-index: 1; display: flex; flex-wrap: wrap; align-items: center; + padding-right: 42px; } .vz-pro-label-wrap h3 { opacity: .7; color: #000000; + font-size: 13px; + line-height: 16px; } .vz-pro-label-wrap span.pro-label{ - margin-left: 30px; + position: absolute; + top: 8px; + right: 8px; + margin-left: 0; font-weight: 600; + font-size: 11px; + line-height: 14px; + padding: 2px 8px 3px; } .vz-chart-option input[type=radio].vz-radio-btn:checked ~ .bg{ background: #BDE6EB; @@ -1215,6 +1398,9 @@ display: none; background: #39C3D2; transition: all .3s ease-in-out; } +.vz-import-status{ + margin-top: 12px; +} .vz-chart-list .slick-arrow[disabled="disabled"], .vz-chart-list .slick-arrow[aria-disabled="true"] { color: #eeeeee } @@ -1253,7 +1439,8 @@ display: none; .vz-document-list > ul > li{width: 100%;} .vz-help-improve-box .left{width: 100%;} .vz-help-improve-box .right{width: 100%;} - .vz-chart-list > ul > li{width: 100%; max-width: 100%; padding-bottom: 30px;} + .vz-chart-list > ul{grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px;} + .vz-chart-list > ul > li{width: 100%; max-width: 100%; padding-bottom: 0;} .vz-shortcode-preview-content{padding-right: 20px;} .vz-newsletter-wrap .vz-newsletter, .vz-newsletter-wrap .vz-newsletter-img{width: 100%; padding-bottom: 20px;} -} \ No newline at end of file +} diff --git a/images/newsletter-img.png b/images/newsletter-img.png deleted file mode 100644 index 04315feaf..000000000 Binary files a/images/newsletter-img.png and /dev/null differ diff --git a/images/otter-logo.png b/images/otter-logo.png new file mode 100644 index 000000000..7fd7d752e Binary files /dev/null and b/images/otter-logo.png differ diff --git a/images/spc-logo.svg b/images/spc-logo.svg new file mode 100644 index 000000000..742554310 --- /dev/null +++ b/images/spc-logo.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/js/setup-wizard.js b/js/setup-wizard.js index fbca0d2dd..d512d12a4 100644 --- a/js/setup-wizard.js +++ b/js/setup-wizard.js @@ -29,6 +29,8 @@ jQuery(function ($) { postData.step ??= 'step_subscribe'; // Subscribe the user using the email if provided. Redirect to the draft page. + var $currentStep = $('#step-3'); + $.post(visualizerSetupWizardData.ajax.url, postData, function (res) { // Toggle the redirect popup. @@ -42,75 +44,142 @@ jQuery(function ($) { } else { $('.redirect-popup').hide(); } - currentStep.find('.spinner').removeClass('is-active'); + $currentStep.find('.spinner').removeClass('is-active'); }).fail(function () { $('.redirect-popup').hide(); - currentStep.find('.spinner').removeClass('is-active'); + $currentStep.find('.spinner').removeClass('is-active'); }); } - var provideContent = function(id, stepDirection, stepPosition, selStep, callback) { - // Import chart data. - if ( 1 == id ) { - var chartType = $(".vz-radio-btn:checked").val(); - var percentBarWidth = 0; - var loaderDelay; - $.ajax( { - beforeSend: function() { - loaderDelay = setInterval(function () { - $('.vz-progress-bar').css({ - width: percentBarWidth++ + '%' - }); - }, 1000); - }, - type: 'POST', - url: visualizerSetupWizardData.ajax.url, - dataType: 'json', - data: { - action: 'visualizer_wizard_step_process', - security: visualizerSetupWizardData.ajax.security, - chart_type: chartType, - step: 'step_2', - }, - success: function (data) { - clearInterval( loaderDelay ); - loaderDelay = setInterval(function () { - $('.vz-progress-bar').css({ - width: percentBarWidth++ + '%' - }); - if ( percentBarWidth >= 100 ) { - if ( 1 === data.success ) { - var importMessage = jQuery('[data-import_message]'); - importMessage - .html( importMessage.data('import_message') ) - .addClass('import_message'); + var runImport = function () { + var chartType = $(".vz-radio-btn:checked").val(); + var percentBarWidth = 0; + var loaderDelay; + var $step = $('#step-1'); + var $status = $step.find('.vz-import-status'); + var $progress = $status.find('.vz-progress-bar'); + var $message = $status.find('[data-import_message]'); + var $error = $status.find('.vz-error-notice'); + var $spinner = $step.find('.spinner'); + var $button = $step.find('[data-step_number="1"]'); + + $status.show(); + $progress.css({ width: '0' }); + if ($message.length) { + $message + .text($message.data('import_initial')) + .removeClass('import_message'); + } + $error.addClass('hidden').empty(); + $spinner.addClass('is-active'); + $button.addClass('disabled'); + + loaderDelay = setInterval(function () { + percentBarWidth = Math.min(percentBarWidth + 4, 90); + $progress.css({ width: percentBarWidth + '%' }); + }, 120); - $('#step-2').find('button.disabled').removeClass('disabled'); - } else if( 2 === data.status && '' !== data.message ) { - $('#step-2') - .find('.vz-error-notice') - .html( '

' + data.message + '

' ) - .removeClass('hidden'); - } else { - $('#smartwizard').smartWizard('reset'); - } - $('.vz-progress-bar').css({ - width: 100 + '%' - }); - $('.vz-progress').css({ - visibility: 'hidden' - }); - clearInterval( loaderDelay ); + $.ajax({ + type: 'POST', + url: visualizerSetupWizardData.ajax.url, + dataType: 'json', + data: { + action: 'visualizer_wizard_step_process', + security: visualizerSetupWizardData.ajax.security, + chart_type: chartType, + step: 'step_2', + }, + success: function (data) { + clearInterval(loaderDelay); + $progress.css({ width: '100%' }); + + if (1 === data.success) { + if (data.chart_id) { + var $shortcode = $('#basic_shortcode'); + if ($shortcode.length) { + $shortcode.val( + $shortcode.val().replace('{{chart_id}}', data.chart_id) + ); } - }, 36 ); - }, - error: function() { - $('#step-2').find('.vz-progress-bar').animate({ width: '0' }); + } + if ($message.length) { + $message + .text($message.data('import_message')) + .addClass('import_message'); + } + + setTimeout(function () { + $spinner.removeClass('is-active'); + $('#smartwizard').smartWizard('next'); + }, 200); + } else if (2 === data.status && '' !== data.message) { + $error.html('

' + data.message + '

').removeClass('hidden'); + $spinner.removeClass('is-active'); + $button.removeClass('disabled'); + } else { + $spinner.removeClass('is-active'); + $button.removeClass('disabled'); + $('#smartwizard').smartWizard('reset'); } - } ); + }, + error: function () { + clearInterval(loaderDelay); + $progress.css({ width: '0' }); + $spinner.removeClass('is-active'); + $button.removeClass('disabled'); + } + }); + }; + + var collectInstallSlugs = function () { + var slugs = []; + var $optimole = $('#enable_performance'); + if ($optimole.length && $optimole.is(':checked') && !$optimole.is(':disabled')) { + slugs.push('optimole-wp'); } - callback(); - } + if ($('#enable_otter_blocks').is(':checked') && !$('#enable_otter_blocks').is(':disabled')) { + slugs.push('otter-blocks'); + } + if ($('#enable_page_cache').is(':checked') && !$('#enable_page_cache').is(':disabled')) { + slugs.push('wp-cloudflare-page-cache'); + } + return slugs; + }; + + var setInstallStatus = function (slug, statusClass) { + var $status = $('[data-install-status="' + slug + '"]'); + $status.removeClass('is-installing is-done is-error').addClass(statusClass); + }; + + var installPluginsSequentially = function (slugs, onDone) { + if (!slugs.length) { + onDone(true); + return; + } + var slug = slugs.shift(); + setInstallStatus(slug, 'is-installing'); + $.post( + visualizerSetupWizardData.ajax.url, + { + action: 'visualizer_wizard_step_process', + security: visualizerSetupWizardData.ajax.security, + slug: slug, + step: 'step_4', + }, + function (response) { + if (1 === response.status) { + setInstallStatus(slug, 'is-done'); + installPluginsSequentially(slugs, onDone); + } else { + setInstallStatus(slug, 'is-error'); + onDone(false, response.message); + } + } + ).fail(function () { + setInstallStatus(slug, 'is-error'); + onDone(false, ''); + }); + }; $("#smartwizard").smartWizard({ transition: { animation: "fade", // Animation effect on navigation, none|fade|slideHorizontal|slideVertical|slideSwing|css(Animation CSS class also need to specify) @@ -133,8 +202,7 @@ jQuery(function ($) { btnCss: "", btnNextCss: "btn-primary next-btn", btnPrevCss: "btn-light", - }, - getContent: provideContent + } }); // click to open accordion. @@ -168,47 +236,19 @@ jQuery(function ($) { switch (stepNumber) { case 1: if ($(".vz-radio-btn").is(":checked")) { - $('#smartwizard').smartWizard('next'); + runImport(); } break; - case 3: + case 2: if ( isLivePreview ) { $('#smartwizard').smartWizard('next'); } else { var urlParams = new URLSearchParams(window.location.search); urlParams.set('preview_chart', Date.now()); - window.location.hash = "#step-3"; + window.location.hash = "#step-2"; window.location.search = urlParams; } break; - case 4: - $('#step-4').find('.spinner').addClass('is-active'); - $('#step-4').find('.vz-error-notice').addClass('hidden'); - - $.post( - visualizerSetupWizardData.ajax.url, - { - action: 'visualizer_wizard_step_process', - security: visualizerSetupWizardData.ajax.security, - slug: 'optimole-wp', - step: 'step_4', - }, - function (response) { - if (1 === response.status) { - $('#smartwizard').smartWizard('next'); - } else if ( 'undefined' !== typeof response.message ) { - $('#step-4') - .find('.vz-error-notice') - .html("

" + response.message + "

"); - $('#step-4').find('.vz-error-notice').removeClass('hidden'); - } - $('#step-4').find('.spinner').removeClass('is-active'); - } - ).fail(function () { - $('#step-4').find('.spinner').removeClass('is-active'); - }); - e.preventDefault(); - break; default: e.preventDefault(); break; @@ -246,16 +286,6 @@ jQuery(function ($) { }); // Enable performance feature. - $("#step-4").on("change", "input:checkbox", function () { - if ($(this).is(":checked")) { - $(".skip-improvement").hide(); - $(".vz-wizard-install-plugin").show(); - } else { - $(".skip-improvement").show(); - $(".vz-wizard-install-plugin").hide(); - } - }); - // Step: 4 Skip and subscribe process. $(document).on( 'click', '.vz-subscribe', function (e) { var withSubscribe = $(this).data("vz_subscribe"); @@ -267,8 +297,9 @@ jQuery(function ($) { var emailElement = $("#vz_subscribe_email"); // Remove error message. emailElement.next(".vz-field-error").remove(); + var newsletterEnabled = $("#enable_newsletter").is(":checked"); - if (withSubscribe) { + if (withSubscribe && newsletterEnabled) { var subscribeEmail = emailElement.val(); var EmailTest = /^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/; var errorMessage = ""; @@ -285,14 +316,49 @@ jQuery(function ($) { postData.email = subscribeEmail; postData.with_subscribe = withSubscribe; + } else { + postData.with_subscribe = false; } - var currentStep = $( '.vz-wizard-wrap .tab-pane:last-child' ); - currentStep.find(".spinner").addClass("is-active"); + var $step = $('#step-3'); + $step.find(".spinner").addClass("is-active"); + var $error = $step.find('.vz-error-notice').first(); + $error.addClass('hidden').empty(); - goToDraftPage( postData ); + var slugs = collectInstallSlugs(); + installPluginsSequentially(slugs.slice(), function (ok, message) { + if (!ok) { + if (message) { + $error.html('

' + message + '

').removeClass('hidden'); + } + $step.find(".spinner").removeClass("is-active"); + return; + } + goToDraftPage(postData); + }); e.preventDefault(); }); + $(document).on('click', '.vz-change-email', function () { + var $card = $(this).closest('.vz-option-card--newsletter'); + var $inputWrap = $card.find('.vz-option-input'); + $inputWrap.show(); + $card.find('#vz_subscribe_email').focus(); + }); + + var finalizeNewsletterEmail = function ($card) { + var $input = $card.find('#vz_subscribe_email'); + var $text = $card.find('.vz-email-text'); + var email = $input.val(); + if (email) { + $text.text(email); + } + $card.find('.vz-option-input').hide(); + }; + + $(document).on('click', '.vz-save-email', function () { + finalizeNewsletterEmail($(this).closest('.vz-option-card--newsletter')); + }); + // Click to copy. var clipboard = new ClipboardJS(".vz-copy-code-btn"); clipboard.on("success", function (e) { @@ -319,29 +385,6 @@ jQuery(function ($) { } }); - $('.vz-chart-list > ul').slick({ - dots: false, - infinite: false, - speed: 400, - slidesToShow: 1, - centerMode: false, - variableWidth: true - }) - .on( 'afterChange', function(event, slick, currentSlide) { - // Disable next buttion. - if( currentSlide === 4 ) { - $('.slick-next').attr('disabled', true).css('pointer-events', 'none'); - } else { - $('.slick-next').removeAttr('disabled').css('pointer-events', 'all'); - } - // Disable prev buttion. - if( currentSlide === 0 ) { - $('.slick-prev').attr('disabled', true).css('pointer-events', 'none'); - } else { - $('.slick-prev').removeAttr('disabled').css('pointer-events', 'all'); - } - } ); - $(window).bind('pageshow', function() { if ( jQuery('.vz-chart-option input').is(':checked') ) { $('#step-1').find('button.disabled').removeClass('disabled'); diff --git a/templates/setup-wizard.php b/templates/setup-wizard.php index 38f1619b7..066980b0a 100644 --- a/templates/setup-wizard.php +++ b/templates/setup-wizard.php @@ -16,7 +16,9 @@ $chart_id = ! empty( $this->wizard_data['chart_id'] ) ? (int) $this->wizard_data['chart_id'] : ''; $wp_optimole_active = is_plugin_active( 'optimole-wp/optimole-wp.php' ); -$last_step_number = 5; +$wp_otter_active = is_plugin_active( 'otter-blocks/otter-blocks.php' ); +$wp_spc_active = is_plugin_active( 'wp-cloudflare-page-cache/wp-cloudflare-super-page-cache.php' ); +$last_step_number = 3; // Check if we are in the Live Preview which is used to showcase only the plugin features without any other distractions. Ideal for marketing purposes (like Live Preview on WordPress.org or on the plugin's website) $is_live_preview = ! empty( $_GET['env'] ) ? ( 'preview' === sanitize_key( $_GET['env'] ) ) : false; @@ -51,31 +53,12 @@ 2 - - - - - - - - +
@@ -147,18 +130,193 @@ class="btn btn-secondary" target="_blank">
  • -
    -

    -
      -
    • -
    • -
    • -
    • - ) -
    • -
    • -
    - +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
    +
    +
  • +
  • +
    + +
    +
    + +
    +
  • @@ -166,48 +324,20 @@ class="btn btn-secondary" target="_blank">
    -
    -
    - - - -
    -
    -
    -
    -

    -

    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    -

    -

    -
    -
    -
    -
    -
    + + -

    -
    -
    -
    +
    @@ -218,42 +348,38 @@ class="btn btn-secondary" target="_blank">
    -
    -
    -
    -
    -
    - > -
    - +
    +
    +
    +
    + > +
    +
    +
    +

    -
    -
    - - -

    -

    - -

    -
    - -
    - -
    - - +
    +
    +
    + + +

    +

    + +

    +
    +
    + +
    + +
    @@ -268,88 +394,118 @@ class="btn btn-secondary" target="_blank">
    - -
    + +
    -

    -

    +

    +

    -
    +
    -
    -
    -
    -
    - +
    +
    + +
    + +
    +
    +
    + +
    - +

    + +

    +
    + +
    +
    + +
    +
    -
    -
    -
      -
    • -
      - -
      -
      -
      -

      -
      -
    • -
    +
    +
    + +
    +

    + +

    +
    -
    -
    -
    - - -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -

    -

    -
    -
    -
    -
    -
    -
    -
    -

    -
    - +
    + +
    +
    +
    +
    + + +
    +

    + +

    +
    +
    -
    - +
    - - +
    diff --git a/tests/e2e/specs/onboarding.spec.ts b/tests/e2e/specs/onboarding.spec.ts index 245708159..a08814d6d 100644 --- a/tests/e2e/specs/onboarding.spec.ts +++ b/tests/e2e/specs/onboarding.spec.ts @@ -31,56 +31,44 @@ test.describe( 'Onboarding', () => { test( 'Check the setup wizard', async ( { page, admin} ) => { await admin.visitAdminPage( 'admin.php?page=visualizer-setup-wizard#step-1' ); + await page.addStyleTag({ content: '#wpfooter{display:none !important;}' }); // Step 1 await expect(page.getByLabel('Pie/Donut chart', { exact: true })).toBeVisible(); await page.getByLabel('Bar chart', { exact: true }).check(); await expect(page.getByLabel('Line chart', { exact: true })).toBeVisible(); await expect(page.getByLabel('Bar chart', { exact: true })).toBeVisible(); - await page.getByLabel('Next', { exact: true }).click(); - await page.getByLabel('Next', { exact: true }).click(); - await page.getByLabel('Next', { exact: true }).click(); - await page.getByLabel('Next', { exact: true }).click(); - await expect(page.getByText('Discover the power of PRO! 11')).toBeVisible(); - await expect(page.getByRole('button', { name: 'Save And Continue ' })).toBeVisible(); + await expect(page.getByRole('button', { name: /Save And Continue/i })).toBeVisible(); await expect(page.getByRole('link', { name: ' Go to dashboard' })).toBeVisible(); - await page.getByRole('button', { name: 'Save And Continue ' }).click(); + await page.getByRole('button', { name: /Save And Continue/i }).click(); // Step 2 - await expect(page.getByLabel('You\'re almost done! We use').locator('h2')).toContainText('You\'re almost done!'); - await expect(page.getByRole('heading', { name: 'Importing demo data' })).toBeVisible(); - await expect(page.getByText('Done! Demo data has been successfully imported.')).toBeVisible(); - await expect(page.getByLabel('You\'re almost done! We use')).toContainText('Import data from other charts, WordPress, databases, or manual data entries using Visualizer'); - await page.getByRole('button', { name: 'Continue ' }).click(); + await expect(page.getByRole('heading', { name: 'Insert a chart into the draft page' })).toBeVisible(); + await expect(page.getByRole('button', { name: /Save And Continue/i })).toBeVisible(); + await page.getByRole('button', { name: /Save And Continue/i }).click(); // Step 3 - await expect(page.getByRole('heading', { name: 'Insert a chart into the draft page' })).toBeVisible(); - await expect(page.getByRole('button', { name: 'Create a draft page We will' })).toBeVisible(); - await page.getByRole('button', { name: 'Create a draft page We will' }).click(); - await expect(page.getByRole('heading', { name: 'Chart preview' })).toBeVisible({ timeout: 15000 }); - await page.getByRole('button', { name: 'Create a draft page We will' }).click(); - await page.getByRole('button', { name: 'Save And Continue ' }).click(); + await expect(page.getByRole('heading', { name: 'You\'re all set!' })).toBeVisible(); + await expect(page.getByText('Boost your website speed')).toBeVisible(); + await expect(page.getByText('Build better pages')).toBeVisible(); + await expect(page.getByText('Cache your pages')).toBeVisible(); + await expect(page.getByText('Stay in the loop')).toBeVisible(); - // Step 4 - await expect(page.getByRole('heading', { name: 'Extra Features' })).toBeVisible(); - await expect(page.getByRole('button', { name: 'Enable perfomance features' })).toBeVisible(); - await page.getByRole('button', { name: 'Enable perfomance features' }).click(); - await expect(page.getByLabel('Extra Features We\'re').getByRole('listitem')).toContainText('Improve your website speed and images by 80% with Optimole'); - await expect(page.getByRole('button', { name: 'Improve now' })).toBeVisible(); - await page.getByRole('checkbox').uncheck(); - await expect(page.getByLabel('Extra Features We\'re')).toContainText('Skip Improvement'); - await page.getByRole('button', { name: 'Skip Improvement' }).click(); + const optimoleCheckbox = page.locator('#enable_performance'); + if (await optimoleCheckbox.isEnabled()) { + await optimoleCheckbox.uncheck(); + } + const otterCheckbox = page.locator('#enable_otter_blocks'); + if (await otterCheckbox.isEnabled()) { + await otterCheckbox.uncheck(); + } + const spcCheckbox = page.locator('#enable_page_cache'); + if (await spcCheckbox.isEnabled()) { + await spcCheckbox.uncheck(); + } + await page.locator('#enable_newsletter').uncheck(); - // Step 5 - await expect(page.getByRole('heading', { name: 'Updates, tutorials, special offers, and more' })).toBeVisible(); - await expect(page.getByLabel('Updates, tutorials, special')).toContainText('Get exclusive access to the Visualizer newsletter.'); - await expect(page.getByLabel('Updates, tutorials, special').locator('img')).toBeVisible(); - await expect(page.getByPlaceholder('test1@xx.com')).toBeVisible(); - await page.getByPlaceholder('test1@xx.com').click(); - await page.getByPlaceholder('test1@xx.com').fill('test@email.com'); - await expect(page.getByLabel('Updates, tutorials, special')).toContainText('Send Me Access'); - await expect(page.getByLabel('Updates, tutorials, special')).toContainText('Skip, Don’t give me access'); - await page.getByRole('button', { name: 'Skip, Don’t give me access' }).click(); + await expect(page.getByRole('button', { name: 'Finish Setup' })).toBeVisible(); } ); } );