Skip to content

Commit 4e9227c

Browse files
committed
Merge branch 'develop' into jdv/menu-position
2 parents 1c6684b + a1cb589 commit 4e9227c

File tree

11 files changed

+68
-298
lines changed

11 files changed

+68
-298
lines changed

.github/workflows/plugin-check.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ jobs:
2626
unzip ${{ github.event.repository.name }}.zip -d build
2727
2828
- name: Run plugin check
29-
uses: wordpress/plugin-check-action@v1.0.6
29+
uses: wordpress/plugin-check-action@v1.1.4
3030
with:
3131
build-dir: './build/${{ github.event.repository.name }}'
32+
exclude-checks: |
33+
direct_file_access

assets/css/onboarding/onboarding.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@
298298
img, svg {
299299
height: 100%;
300300
width: auto;
301+
max-width: 100%;
301302
}
302303
}
303304

assets/js/onboarding/onboarding.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,17 @@ class ProgressPlannerOnboardWizard {
373373
this.state.data.finished =
374374
this.state.currentStep === this.tourSteps.length - 1;
375375
this.closeTour();
376+
377+
// If on PP Dashboard page and privacy was accepted during onboarding,
378+
// refresh the page to properly initialize dashboard components.
379+
if (
380+
this.state.data.privacyAccepted &&
381+
window.location.href.includes(
382+
'admin.php?page=progress-planner'
383+
)
384+
) {
385+
window.location.reload();
386+
}
376387
} );
377388
}
378389
} else {

assets/js/onboarding/steps/SettingsStep.js

Lines changed: 3 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
11
/**
2-
* Settings step - Configure About, Contact, FAQ pages, Post Types, and Login Destination
2+
* Settings step - Configure About, Contact, FAQ pages, and Post Types
33
* Multi-step process with 5 sub-steps
44
*/
55
/* global OnboardingStep, ProgressPlannerOnboardData */
66

77
class PrplSettingsStep extends OnboardingStep {
8-
subSteps = [
9-
'homepage',
10-
'about',
11-
'contact',
12-
'faq',
13-
'post-types',
14-
'login-destination',
15-
];
8+
subSteps = [ 'homepage', 'about', 'contact', 'faq', 'post-types' ];
169

1710
defaultSettings = {
1811
homepage: {
@@ -34,9 +27,6 @@ class PrplSettingsStep extends OnboardingStep {
3427
'post-types': {
3528
selectedTypes: [], // Array of selected post type slugs
3629
},
37-
'login-destination': {
38-
redirectOnLogin: false, // Checkbox state
39-
},
4030
};
4131

4232
constructor() {
@@ -137,7 +127,7 @@ class PrplSettingsStep extends OnboardingStep {
137127

138128
/**
139129
* Setup event listeners for a sub-step
140-
* @param {string} subStepName - Name of sub-step (about/contact/faq/post-types/login-destination)
130+
* @param {string} subStepName - Name of sub-step (about/contact/faq/post-types)
141131
* @param {Object} subStepData - Data for this sub-step
142132
* @param {Object} state - Wizard state
143133
*/
@@ -153,16 +143,6 @@ class PrplSettingsStep extends OnboardingStep {
153143
// Handle post types sub-step
154144
if ( subStepName === 'post-types' ) {
155145
this.setupPostTypesListeners( subStepName, subStepData, state );
156-
return;
157-
}
158-
159-
// Handle login destination sub-step
160-
if ( subStepName === 'login-destination' ) {
161-
this.setupLoginDestinationListeners(
162-
subStepName,
163-
subStepData,
164-
state
165-
);
166146
}
167147
}
168148

@@ -342,60 +322,6 @@ class PrplSettingsStep extends OnboardingStep {
342322
this.updateSaveButtonState( saveButton, subStepData );
343323
}
344324

345-
/**
346-
* Setup event listeners for login destination sub-step
347-
* @param {string} subStepName - Name of sub-step
348-
* @param {Object} subStepData - Data for this sub-step
349-
* @param {Object} state - Wizard state
350-
*/
351-
setupLoginDestinationListeners( subStepName, subStepData, state ) {
352-
const container = this.popover.querySelector(
353-
`.prpl-setting-item[data-page="${ subStepName }"]`
354-
);
355-
const saveButton = this.popover.querySelector(
356-
`#prpl-save-${ subStepName }-setting`
357-
);
358-
359-
if ( ! container || ! saveButton ) {
360-
return;
361-
}
362-
363-
// Get checkbox
364-
const checkbox = container.querySelector(
365-
'input[type="checkbox"][name="prpl-redirect-on-login"]'
366-
);
367-
368-
if ( ! checkbox ) {
369-
return;
370-
}
371-
372-
// Initialize from checkbox that is already set in template, or from saved data
373-
if ( subStepData.redirectOnLogin === undefined ) {
374-
subStepData.redirectOnLogin = checkbox.checked;
375-
} else {
376-
checkbox.checked = subStepData.redirectOnLogin;
377-
}
378-
379-
// Add change listener
380-
checkbox.addEventListener( 'change', ( e ) => {
381-
subStepData.redirectOnLogin = e.target.checked;
382-
this.updateSaveButtonState( saveButton, subStepData );
383-
384-
// Update Next/Dashboard button if on last sub-step
385-
if ( this.currentSubStep === this.subSteps.length - 1 ) {
386-
this.updateNextButton();
387-
}
388-
} );
389-
390-
// Save button handler - just advances to next sub-step
391-
saveButton.addEventListener( 'click', () => {
392-
this.advanceSubStep( state );
393-
} );
394-
395-
// Initial button state
396-
this.updateSaveButtonState( saveButton, subStepData );
397-
}
398-
399325
/**
400326
* Advance to next sub-step
401327
* @param {Object} state - Wizard state
@@ -445,11 +371,6 @@ class PrplSettingsStep extends OnboardingStep {
445371
return subStepData.selectedTypes.length > 0;
446372
}
447373

448-
// Handle login destination sub-step - always valid (checkbox is optional)
449-
if ( subStepData.redirectOnLogin !== undefined ) {
450-
return true;
451-
}
452-
453374
return false;
454375
}
455376

@@ -525,12 +446,6 @@ class PrplSettingsStep extends OnboardingStep {
525446
} );
526447
}
527448

528-
// Add login destination
529-
const loginData = state.data.settings[ 'login-destination' ];
530-
if ( loginData && loginData.redirectOnLogin ) {
531-
formDataObj.append( 'prpl-redirect-on-login', '1' );
532-
}
533-
534449
// Send single AJAX request
535450
const response = await fetch(
536451
ProgressPlannerOnboardData.adminAjaxUrl,

assets/js/web-components/prpl-interactive-task.js

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,6 @@
55
*/
66
// eslint-disable-next-line no-unused-vars
77
class PrplInteractiveTask extends HTMLElement {
8-
// eslint-disable-next-line no-useless-constructor
9-
constructor() {
10-
// Get parent class properties
11-
super();
12-
13-
this.repositionPopover = this.repositionPopover.bind( this ); // So this is available in the event listener.
14-
}
15-
168
/**
179
* Runs when the component is added to the DOM.
1810
*/
@@ -55,20 +47,6 @@ class PrplInteractiveTask extends HTMLElement {
5547
} );
5648
}
5749

58-
/**
59-
* Runs when the popover is added to the DOM.
60-
*/
61-
popoverAddedToDOM() {
62-
window.addEventListener( 'resize', this.repositionPopover );
63-
}
64-
65-
/**
66-
* Runs when the popover is opening.
67-
*/
68-
popoverOpening() {
69-
this.repositionPopover();
70-
}
71-
7250
/**
7351
* Runs when the popover is closing.
7452
*/
@@ -107,63 +85,6 @@ class PrplInteractiveTask extends HTMLElement {
10785
const popover = document.getElementById( popoverId );
10886
popover.hidePopover();
10987
}
110-
111-
/**
112-
* Repositions the popover relative to the target element.
113-
* @private
114-
*/
115-
repositionPopover() {
116-
const horizontalTarget = document.querySelector( '.prpl-wrap' );
117-
const verticalTarget = document.querySelector(
118-
'.prpl-widget-wrapper.prpl-suggested-tasks'
119-
);
120-
121-
// Just in case.
122-
if ( ! horizontalTarget || ! verticalTarget ) {
123-
return;
124-
}
125-
126-
const horizontalRect = horizontalTarget.getBoundingClientRect();
127-
const verticalRect = verticalTarget.getBoundingClientRect();
128-
const popoverId = this.getAttribute( 'popover-id' );
129-
const popover = document.getElementById( popoverId );
130-
131-
// Reset default popover styles.
132-
popover.style.margin = '0';
133-
134-
// Calculate target's center
135-
const horizontalTargetCenter =
136-
horizontalRect.left + horizontalRect.width / 2;
137-
138-
// Ensure that the popover is not too far from the top of the screen on small screens.
139-
const MARGIN_TOP = 12; // minimum gap from top
140-
const MARGIN_BOTTOM = 12; // minimum gap from bottom
141-
const MOBILE_TOP_CAP = 100; // max starting offset on small screens
142-
const isSmallScreen = window.matchMedia( '(max-width: 768px)' ).matches;
143-
const MAX_TOP_CAP = isSmallScreen
144-
? MOBILE_TOP_CAP
145-
: Number.POSITIVE_INFINITY;
146-
147-
const desiredTop = Math.round( verticalRect.top );
148-
149-
const clampedTop = Math.max(
150-
MARGIN_TOP,
151-
Math.min( desiredTop, MAX_TOP_CAP )
152-
);
153-
154-
// Apply the position.
155-
popover.style.position = 'fixed';
156-
popover.style.left = `${ horizontalTargetCenter }px`;
157-
popover.style.top = `${ Math.round( clampedTop ) }px`;
158-
popover.style.transform = 'translateX(-50%)';
159-
160-
// Make sure popover content can scroll if needed
161-
popover.style.maxHeight = '80vh'; // adjustable
162-
popover.style.overflowY = 'auto';
163-
popover.style.maxHeight = `calc(100vh - ${
164-
clampedTop + MARGIN_BOTTOM
165-
}px)`;
166-
}
16788
}
16889

16990
/**

classes/class-onboard-wizard.php

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,36 @@
1212
*/
1313
class Onboard_Wizard {
1414

15+
/**
16+
* Option name for storing onboarding progress.
17+
*
18+
* @var string
19+
*/
20+
public const PROGRESS_OPTION_NAME = 'prpl_onboard_progress';
21+
1522
/**
1623
* Steps and their order.
1724
*
1825
* @var array
1926
*/
2027
protected $steps = [];
2128

29+
/**
30+
* Delete the onboarding progress option.
31+
*
32+
* @return bool True if the option was deleted, false otherwise.
33+
*/
34+
public static function delete_progress() {
35+
return \delete_option( self::PROGRESS_OPTION_NAME );
36+
}
37+
2238
/**
2339
* Constructor.
2440
*
2541
* @return void
2642
*/
2743
public function __construct() {
28-
\add_action( 'init', [ $this, 'maybe_register_popover_hooks' ], 0 );
44+
\add_action( 'init', [ $this, 'maybe_register_popover_hooks' ], 10 ); // Wait for the Playground to register its hooks.
2945
}
3046

3147
/**
@@ -51,21 +67,21 @@ public function maybe_register_popover_hooks() {
5167
// 2. Onboarding already in progress.
5268
// 3. Branded site (privacy auto-accepted, but still needs onboarding).
5369
$is_branded = 0 !== (int) \progress_planner()->get_ui__branding()->get_branding_id();
54-
$skip_onboarding = \progress_planner()->is_privacy_policy_accepted()
55-
&& ! \get_option( 'prpl_onboard_progress', false )
56-
&& ! $is_branded;
70+
$show_onboarding = ! \progress_planner()->is_privacy_policy_accepted()
71+
|| \get_option( self::PROGRESS_OPTION_NAME, false )
72+
|| $is_branded;
5773

5874
/**
59-
* Filter whether to skip the onboarding wizard.
75+
* Filter whether to show the onboarding wizard.
6076
*
6177
* Hosting integrations can use this filter to force showing
6278
* or hiding the onboarding wizard.
6379
*
64-
* @param bool $skip_onboarding Whether to skip showing the onboarding wizard.
80+
* @param bool $show_onboarding Whether to show the onboarding wizard.
6581
*/
66-
$skip_onboarding = \apply_filters( 'progress_planner_skip_onboarding', $skip_onboarding );
82+
$show_onboarding = \apply_filters( 'progress_planner_show_onboarding', $show_onboarding );
6783

68-
if ( $skip_onboarding ) {
84+
if ( ! $show_onboarding ) {
6985
return;
7086
}
7187

@@ -319,7 +335,7 @@ protected function get_saved_progress() {
319335
return null;
320336
}
321337

322-
$onboarding_progress = \get_option( 'prpl_onboard_progress', true );
338+
$onboarding_progress = \get_option( self::PROGRESS_OPTION_NAME, true );
323339
if ( ! $onboarding_progress ) {
324340
return null;
325341
}
@@ -363,7 +379,7 @@ public function ajax_save_onboarding_progress() {
363379
\error_log( print_r( $progress, true ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r, WordPress.PHP.DevelopmentFunctions.error_log_error_log
364380

365381
// Save as user meta?
366-
\update_option( 'prpl_onboard_progress', $progress );
382+
\update_option( self::PROGRESS_OPTION_NAME, $progress );
367383

368384
\wp_send_json_success( [ 'message' => \esc_html__( 'Tour progress saved.', 'progress-planner' ) ] );
369385
}

classes/class-plugin-upgrade-tasks.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ public function handle_activation_or_upgrade() {
8383
* @return void
8484
*/
8585
protected function add_initial_onboarding_tasks() {
86-
// Privacy policy is not accepted, so it's a fresh install.
87-
$fresh_install = ! \progress_planner()->is_privacy_policy_accepted();
86+
// Check if this is a fresh install (not a re-activation).
87+
// If the option doesn't exist, it's a fresh install.
88+
$fresh_install = false === \get_option( 'progress_planner_previous_version_task_providers', false );
8889

8990
// If this is the first time the plugin is installed, save the task providers.
9091
if ( $fresh_install ) {

classes/utils/class-debug-tools.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ public function check_delete_onboarding_progress() {
791791
$this->verify_nonce();
792792

793793
// Delete the onboarding progress.
794-
\delete_option( 'prpl_onboard_progress' );
794+
\Progress_Planner\Onboard_Wizard::delete_progress();
795795

796796
// Delete the license key.
797797
\delete_option( 'progress_planner_license_key' );

0 commit comments

Comments
 (0)