Skip to content

Commit 5f89208

Browse files
authored
Merge pull request #548 from ProgressPlanner/ari/plugin-installer
Add a plugin-installer component for recommendations
2 parents 4e4327e + 2a455c5 commit 5f89208

8 files changed

Lines changed: 526 additions & 3 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
prpl-install-plugin {
2+
3+
button {
4+
display: flex !important;
5+
align-items: center;
6+
justify-content: center;
7+
gap: 0.5rem;
8+
}
9+
10+
.prpl-install-button-loader {
11+
display: none;
12+
width: 1rem;
13+
height: 1rem;
14+
border: 3px solid var(--prpl-color-link);
15+
border-bottom-color: transparent;
16+
border-radius: 50%;
17+
box-sizing: border-box;
18+
animation: install-button-rotation 1s linear infinite;
19+
}
20+
21+
button:disabled {
22+
opacity: 0.5;
23+
cursor: not-allowed;
24+
25+
.prpl-install-button-loader {
26+
display: block;
27+
}
28+
}
29+
30+
.prpl-button-link {
31+
text-decoration: underline;
32+
color: var(--prpl-color-link);
33+
background: none;
34+
border: none;
35+
padding: 0;
36+
margin: 0;
37+
font-size: inherit;
38+
font-weight: inherit;
39+
line-height: inherit;
40+
text-align: inherit;
41+
cursor: pointer;
42+
}
43+
}
44+
45+
@keyframes install-button-rotation {
46+
47+
0% {
48+
transform: rotate(0deg);
49+
}
50+
51+
100% {
52+
transform: rotate(360deg);
53+
}
54+
}

assets/js/recommendations/disable-comments.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/*
44
* Disable Comments recommendation.
55
*
6-
* Dependencies: progress-planner/recommendations/interactive-task
6+
* Dependencies: progress-planner/recommendations/interactive-task, progress-planner/web-components/prpl-install-plugin
77
*/
88

99
prplInteractiveTaskFormListener.siteSettings( {
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/* global customElements, HTMLElement, prplL10n, progressPlanner, progressPlannerAjaxRequest, prplSuggestedTask */
2+
/*
3+
* Install Plugin
4+
*
5+
* A web component to install a plugin.
6+
*
7+
* Dependencies: progress-planner/l10n, progress-planner/ajax-request, progress-planner/suggested-task
8+
*/
9+
10+
/**
11+
* Register the custom web component.
12+
*/
13+
customElements.define(
14+
'prpl-install-plugin',
15+
class extends HTMLElement {
16+
constructor(
17+
pluginSlug,
18+
pluginName,
19+
action,
20+
providerId,
21+
className = 'prpl-button-link'
22+
) {
23+
// Get parent class properties
24+
super();
25+
26+
this.pluginSlug =
27+
pluginSlug ?? this.getAttribute( 'data-plugin-slug' );
28+
this.pluginName =
29+
pluginName ?? this.getAttribute( 'data-plugin-name' );
30+
this.pluginName = this.pluginName ?? this.pluginSlug;
31+
this.action = action ?? this.getAttribute( 'data-action' );
32+
this.providerId =
33+
providerId ?? this.getAttribute( 'data-provider-id' );
34+
this.className = className ?? this.getAttribute( 'class' );
35+
// If the plugin slug is empty, bail out.
36+
if ( ! this.pluginSlug ) {
37+
return;
38+
}
39+
40+
// Set the inner HTML.
41+
this.innerHTML = `
42+
<button type="button" class="${ this.className }">
43+
${ prplL10n(
44+
'install' === this.action
45+
? 'installPlugin'
46+
: 'activatePlugin'
47+
).replace( '%s', this.pluginName ) }
48+
</button>
49+
`;
50+
51+
// Handle the click event.
52+
this.handleClick();
53+
}
54+
55+
/**
56+
* Handle the click event.
57+
*/
58+
handleClick() {
59+
const button = this.querySelector( 'button' );
60+
if ( ! button ) {
61+
return;
62+
}
63+
64+
button.addEventListener( 'click', () => {
65+
button.disabled = true;
66+
if ( 'install' === this.action ) {
67+
this.installPlugin();
68+
} else {
69+
this.activatePlugin();
70+
}
71+
} );
72+
}
73+
74+
installPlugin() {
75+
const button = this.querySelector( 'button' );
76+
const thisObj = this;
77+
78+
button.innerHTML = `
79+
<span class="prpl-install-button-loader"></span>
80+
${ prplL10n( 'installing' ) }
81+
`;
82+
83+
progressPlannerAjaxRequest( {
84+
url: progressPlanner.ajaxUrl,
85+
data: {
86+
action: 'progress_planner_install_plugin',
87+
plugin_slug: this.pluginSlug,
88+
plugin_name: this.pluginName,
89+
nonce: progressPlanner.nonce,
90+
},
91+
} )
92+
.then( () => thisObj.activatePlugin() )
93+
.catch( ( error ) => console.error( error ) );
94+
}
95+
96+
activatePlugin() {
97+
const button = this.querySelector( 'button' );
98+
const thisObj = this;
99+
button.innerHTML = `
100+
<span class="prpl-install-button-loader"></span>
101+
${ prplL10n( 'activating' ) }
102+
`;
103+
104+
progressPlannerAjaxRequest( {
105+
url: progressPlanner.ajaxUrl,
106+
data: {
107+
action: 'progress_planner_activate_plugin',
108+
plugin_slug: thisObj.pluginSlug,
109+
plugin_name: thisObj.pluginName,
110+
nonce: progressPlanner.nonce,
111+
},
112+
} )
113+
.then( () => {
114+
button.innerHTML = prplL10n( 'activated' );
115+
thisObj.completeTask();
116+
} )
117+
.catch( ( error ) => console.error( error ) );
118+
}
119+
120+
/**
121+
* Complete the task.
122+
*/
123+
completeTask() {
124+
const tasks = document.querySelectorAll(
125+
'#prpl-suggested-tasks-list .prpl-suggested-task'
126+
);
127+
const thisObj = this;
128+
129+
tasks.forEach( ( taskElement ) => {
130+
if ( taskElement.dataset.taskId === thisObj.providerId ) {
131+
// Close popover.
132+
document
133+
.getElementById( 'prpl-popover-' + thisObj.providerId )
134+
.hidePopover();
135+
136+
const postId = parseInt( taskElement.dataset.postId );
137+
138+
if ( postId ) {
139+
prplSuggestedTask.maybeComplete( postId );
140+
}
141+
}
142+
} );
143+
}
144+
}
145+
);

classes/admin/class-enqueue.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,17 @@ public function get_localized_strings() {
380380
'watchVideo' => \esc_html__( 'Watch video', 'progress-planner' ),
381381
'disabledRRCheckboxTooltip' => \esc_html__( 'Don\'t worry! This task will be checked off automatically when you\'ve completed it.', 'progress-planner' ),
382382
'opensInNewWindow' => \esc_html__( 'Opens in new window', 'progress-planner' ),
383+
/* translators: %s: The plugin name. */
384+
'installPlugin' => \esc_html__( 'Install and activate the "%s" plugin', 'progress-planner' ),
385+
/* translators: %s: The plugin name. */
386+
'activatePlugin' => \esc_html__( 'Activate plugin "%s"', 'progress-planner' ),
387+
'installing' => \esc_html__( 'Installing...', 'progress-planner' ),
388+
'installed' => \esc_html__( 'Installed', 'progress-planner' ),
389+
'alreadyInstalled' => \esc_html__( 'Already installed', 'progress-planner' ),
390+
'installFailed' => \esc_html__( 'Install failed', 'progress-planner' ),
391+
'activating' => \esc_html__( 'Activating...', 'progress-planner' ),
392+
'activated' => \esc_html__( 'Activated', 'progress-planner' ),
393+
'activateFailed' => \esc_html__( 'Activation failed', 'progress-planner' ),
383394
];
384395
}
385396
}

classes/admin/class-page.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ public function enqueue_styles() {
278278

279279
\progress_planner()->get_admin__enqueue()->enqueue_style( 'progress-planner/admin' );
280280
\progress_planner()->get_admin__enqueue()->enqueue_style( 'progress-planner/web-components/prpl-tooltip' );
281+
\progress_planner()->get_admin__enqueue()->enqueue_style( 'progress-planner/web-components/prpl-install-plugin' );
281282

282283
if ( 'progress-planner_page_progress-planner-settings' === $current_screen->id ) {
283284
\progress_planner()->get_admin__enqueue()->enqueue_style( 'progress-planner/settings-page' );

classes/class-base.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
* @method \Progress_Planner\Suggested_Tasks get_suggested_tasks()
4141
* @method \Progress_Planner\Suggested_Tasks_DB get_suggested_tasks_db()
4242
* @method \Progress_Planner\Utils\Deprecations get_utils__deprecations()
43+
* @method \Progress_Planner\Plugin_Installer get_plugin_installer()
4344
*/
4445
class Base {
4546

@@ -142,6 +143,9 @@ public function init() {
142143
// Plugin upgrade.
143144
$this->get_plugin_migrations();
144145

146+
// Plugin installer.
147+
$this->get_plugin_installer();
148+
145149
/**
146150
* Redirect on login.
147151
*/

0 commit comments

Comments
 (0)