Skip to content

Commit c681760

Browse files
authored
Merge pull request #516 from ProgressPlanner/filip/v16/preload-tasks
Preload tasks
2 parents bf23df6 + f84d002 commit c681760

7 files changed

Lines changed: 368 additions & 105 deletions

File tree

assets/js/suggested-task.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,32 @@ prplSuggestedTask = {
9999
return data;
100100
} ),
101101

102+
/**
103+
* Inject items.
104+
*
105+
* @param {Object[]} items The items to inject.
106+
*/
107+
injectItems: ( items ) => {
108+
if ( items.length ) {
109+
// Inject the items into the DOM.
110+
items.forEach( ( item ) => {
111+
document.dispatchEvent(
112+
new CustomEvent( 'prpl/suggestedTask/injectItem', {
113+
detail: {
114+
item,
115+
listId: 'prpl-suggested-tasks-list',
116+
insertPosition: 'beforeend',
117+
},
118+
} )
119+
);
120+
prplSuggestedTask.injectedItemIds.push( item.id );
121+
} );
122+
}
123+
124+
// Trigger the grid resize event.
125+
window.dispatchEvent( new CustomEvent( 'prpl/grid/resize' ) );
126+
},
127+
102128
/**
103129
* Get a collection of posts.
104130
*

assets/js/widgets/suggested-tasks.js

Lines changed: 114 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -29,59 +29,45 @@ const prplSuggestedTasksWidget = {
2929
return;
3030
}
3131

32-
const celebrationPromises = [];
33-
34-
// Loop through each provider and inject items.
35-
for ( const category in prplSuggestedTask.maxItemsPerCategory ) {
36-
if ( 'user' === category ) {
37-
continue;
38-
}
39-
40-
// Inject published tasks.
41-
prplSuggestedTask.injectItemsFromCategory( {
42-
category,
43-
status: [ 'publish' ],
44-
per_page: prplSuggestedTask.maxItemsPerCategory[ category ],
45-
} );
46-
47-
// We trigger celebration only on Progress Planner dashboard page.
48-
if ( ! prplSuggestedTask.delayCelebration ) {
49-
// Inject pending celebration tasks.
50-
celebrationPromises.push(
51-
prplSuggestedTask
52-
.injectItemsFromCategory( {
53-
category,
54-
status: [ 'pending' ],
55-
per_page: 100,
56-
} )
57-
.then( ( data ) => {
58-
// If there were pending tasks.
59-
if ( data.length ) {
60-
// Set post status to trash.
61-
data.forEach( ( task ) => {
62-
const post =
63-
new wp.api.models.Prpl_recommendations(
64-
{
65-
id: task.id,
66-
}
67-
);
68-
// Destroy the post, without the force parameter.
69-
post.destroy( { url: post.url() } );
70-
} );
71-
}
72-
} )
32+
// If preloaded tasks are available, inject them.
33+
if ( 'undefined' !== typeof prplSuggestedTask.tasks ) {
34+
// Inject the tasks.
35+
if ( Object.keys( prplSuggestedTask.tasks.pendingTasks ).length ) {
36+
Object.keys( prplSuggestedTask.tasks.pendingTasks ).forEach(
37+
( category ) => {
38+
prplSuggestedTask.injectItems(
39+
prplSuggestedTask.tasks.pendingTasks[ category ]
40+
);
41+
}
7342
);
7443
}
75-
}
7644

77-
// Trigger celebration once, for all categories.
78-
Promise.all( celebrationPromises ).then( () => {
45+
// Inject the pending celebration tasks.
7946
if (
80-
0 <
81-
document.querySelectorAll(
82-
'.prpl-suggested-tasks-list [data-task-action="celebrate"]'
83-
).length
47+
Object.keys( prplSuggestedTask.tasks.pendingCelebrationTasks )
48+
.length
8449
) {
50+
Object.keys(
51+
prplSuggestedTask.tasks.pendingCelebrationTasks
52+
).forEach( ( category ) => {
53+
prplSuggestedTask.injectItems(
54+
prplSuggestedTask.tasks.pendingCelebrationTasks[
55+
category
56+
]
57+
);
58+
59+
// Set post status to trash.
60+
prplSuggestedTask.tasks.pendingCelebrationTasks[
61+
category
62+
].forEach( ( task ) => {
63+
const post = new wp.api.models.Prpl_recommendations( {
64+
id: task.id,
65+
} );
66+
// Destroy the post, without the force parameter.
67+
post.destroy( { url: post.url() } );
68+
} );
69+
} );
70+
8571
// Trigger the celebration event (trigger confetti, strike through tasks, remove from DOM).
8672
setTimeout( () => {
8773
// Trigger the celebration event.
@@ -102,7 +88,86 @@ const prplSuggestedTasksWidget = {
10288
);
10389
}, 3000 );
10490
}
105-
} );
91+
92+
// Toggle the "Loading..." text.
93+
prplSuggestedTasksWidget.removeLoadingItems();
94+
} else {
95+
// Otherwise, inject tasks from the API.
96+
const celebrationPromises = [];
97+
98+
// Loop through each provider and inject items.
99+
for ( const category in prplSuggestedTask.maxItemsPerCategory ) {
100+
if ( 'user' === category ) {
101+
continue;
102+
}
103+
104+
// Inject published tasks.
105+
prplSuggestedTask.injectItemsFromCategory( {
106+
category,
107+
status: [ 'publish' ],
108+
per_page: prplSuggestedTask.maxItemsPerCategory[ category ],
109+
} );
110+
111+
// We trigger celebration only on Progress Planner dashboard page.
112+
if ( ! prplSuggestedTask.delayCelebration ) {
113+
// Inject pending celebration tasks.
114+
celebrationPromises.push(
115+
prplSuggestedTask
116+
.injectItemsFromCategory( {
117+
category,
118+
status: [ 'pending' ],
119+
per_page: 100,
120+
} )
121+
.then( ( data ) => {
122+
// If there were pending tasks.
123+
if ( data.length ) {
124+
// Set post status to trash.
125+
data.forEach( ( task ) => {
126+
const post =
127+
new wp.api.models.Prpl_recommendations(
128+
{
129+
id: task.id,
130+
}
131+
);
132+
// Destroy the post, without the force parameter.
133+
post.destroy( { url: post.url() } );
134+
} );
135+
}
136+
} )
137+
);
138+
}
139+
}
140+
141+
// Trigger celebration once, for all categories.
142+
Promise.all( celebrationPromises ).then( () => {
143+
if (
144+
0 <
145+
document.querySelectorAll(
146+
'.prpl-suggested-tasks-list [data-task-action="celebrate"]'
147+
).length
148+
) {
149+
// Trigger the celebration event (trigger confetti, strike through tasks, remove from DOM).
150+
setTimeout( () => {
151+
// Trigger the celebration event.
152+
document.dispatchEvent(
153+
new CustomEvent( 'prpl/celebrateTasks' )
154+
);
155+
156+
/**
157+
* Strike completed tasks and remove them from the DOM.
158+
*/
159+
document.dispatchEvent(
160+
new CustomEvent( 'prpl/removeCelebratedTasks' )
161+
);
162+
163+
// Trigger the grid resize event.
164+
window.dispatchEvent(
165+
new CustomEvent( 'prpl/grid/resize' )
166+
);
167+
}, 3000 );
168+
}
169+
} );
170+
}
106171
},
107172
};
108173

assets/js/widgets/todo.js

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -42,40 +42,70 @@ const prplTodoWidget = {
4242
* Populate the todo list.
4343
*/
4444
populateList: () => {
45-
prplSuggestedTask
46-
.fetchItems( {
47-
category: 'user',
48-
status: [ 'publish', 'trash' ],
49-
per_page: 100,
50-
} )
51-
.then( ( data ) => {
52-
if ( ! data.length ) {
53-
return data;
54-
}
45+
// If preloaded tasks are available, inject them.
46+
if ( 'undefined' !== typeof prplSuggestedTask.tasks ) {
47+
// Inject the tasks.
48+
if ( Object.keys( prplSuggestedTask.tasks.userTasks ).length ) {
49+
Object.values( prplSuggestedTask.tasks.userTasks ).forEach(
50+
( item ) => {
51+
// Inject the items into the DOM.
52+
document.dispatchEvent(
53+
new CustomEvent( 'prpl/suggestedTask/injectItem', {
54+
detail: {
55+
item,
56+
insertPosition:
57+
1 === item?.meta?.prpl_points
58+
? 'afterbegin' // Add golden task to the start of the list.
59+
: 'beforeend',
60+
listId:
61+
item.status === 'publish'
62+
? 'todo-list'
63+
: 'todo-list-completed',
64+
},
65+
} )
66+
);
67+
prplSuggestedTask.injectedItemIds.push( item.id );
68+
}
69+
);
70+
prplTodoWidget.removeLoadingItems();
71+
}
72+
} else {
73+
// Otherwise, inject tasks from the API.
74+
prplSuggestedTask
75+
.fetchItems( {
76+
category: 'user',
77+
status: [ 'publish', 'trash' ],
78+
per_page: 100,
79+
} )
80+
.then( ( data ) => {
81+
if ( ! data.length ) {
82+
return data;
83+
}
5584

56-
// Inject the items into the DOM.
57-
data.forEach( ( item ) => {
58-
document.dispatchEvent(
59-
new CustomEvent( 'prpl/suggestedTask/injectItem', {
60-
detail: {
61-
item,
62-
insertPosition:
63-
1 === item?.meta?.prpl_points
64-
? 'afterbegin' // Add golden task to the start of the list.
65-
: 'beforeend',
66-
listId:
67-
item.status === 'publish'
68-
? 'todo-list'
69-
: 'todo-list-completed',
70-
},
71-
} )
72-
);
73-
prplSuggestedTask.injectedItemIds.push( item.id );
74-
} );
85+
// Inject the items into the DOM.
86+
data.forEach( ( item ) => {
87+
document.dispatchEvent(
88+
new CustomEvent( 'prpl/suggestedTask/injectItem', {
89+
detail: {
90+
item,
91+
insertPosition:
92+
1 === item?.meta?.prpl_points
93+
? 'afterbegin' // Add golden task to the start of the list.
94+
: 'beforeend',
95+
listId:
96+
item.status === 'publish'
97+
? 'todo-list'
98+
: 'todo-list-completed',
99+
},
100+
} )
101+
);
102+
prplSuggestedTask.injectedItemIds.push( item.id );
103+
} );
75104

76-
return data;
77-
} )
78-
.then( () => prplTodoWidget.removeLoadingItems() );
105+
return data;
106+
} )
107+
.then( () => prplTodoWidget.removeLoadingItems() );
108+
}
79109

80110
// When the '#create-todo-item' form is submitted,
81111
// add a new todo item to the list

classes/admin/class-enqueue.php

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
namespace Progress_Planner\Admin;
99

1010
use Progress_Planner\Badges\Monthly;
11-
use Progress_Planner\Suggested_Tasks\Providers\Content_Review;
1211

1312
/**
1413
* Enqueue class.
@@ -199,34 +198,36 @@ public function localize_script( $handle, $localize_data = [] ) {
199198
break;
200199

201200
case 'progress-planner/suggested-task':
202-
// Set max items per category.
203-
$max_items_per_category = [];
204-
$provider_categories = \get_terms(
205-
[
206-
'taxonomy' => 'prpl_recommendations_category',
207-
'hide_empty' => false,
208-
]
209-
);
210-
211-
if ( ! empty( $provider_categories ) && ! is_wp_error( $provider_categories ) ) {
212-
$content_review_category = ( new Content_Review() )->get_provider_category();
213-
foreach ( $provider_categories as $provider_category ) {
214-
$max_items_per_category[ $provider_category->slug ] = $provider_category->slug === $content_review_category ? 2 : 1;
215-
}
216-
}
217-
218-
// This should never happen, but just in case - user tasks are displayed in different widget.
219-
if ( isset( $max_items_per_category['user'] ) ) {
220-
$max_items_per_category['user'] = 100;
221-
}
222-
223201
// Celebrate only on the Progress Planner Dashboard page.
224202
$delay_celebration = true;
225203
if ( \progress_planner()->is_on_progress_planner_dashboard_page() ) {
226204
// should_show_upgrade_popover() also checks if we're on the Progress Planner Dashboard page - but let's be explicit since that method might change in the future.
227205
$delay_celebration = \progress_planner()->get_plugin_upgrade_tasks()->should_show_upgrade_popover();
228206
}
229207

208+
// Get tasks from task providers.
209+
$tasks = \progress_planner()->get_suggested_tasks()->get_tasks_in_rest_format(
210+
[
211+
'post_status' => 'publish',
212+
'exclude_provider' => [ 'user' ],
213+
]
214+
);
215+
// Get pending celebration tasks.
216+
$pending_celebration_tasks = \progress_planner()->get_suggested_tasks()->get_tasks_in_rest_format(
217+
[
218+
'post_status' => 'pending',
219+
'exclude_provider' => [ 'user' ],
220+
]
221+
);
222+
223+
// Get user tasks.
224+
$user_tasks = \progress_planner()->get_suggested_tasks()->get_tasks_in_rest_format(
225+
[
226+
'post_status' => [ 'publish', 'trash' ],
227+
'include_provider' => [ 'user' ],
228+
]
229+
);
230+
230231
$localize_data = [
231232
'name' => 'prplSuggestedTask',
232233
'data' => [
@@ -235,7 +236,12 @@ public function localize_script( $handle, $localize_data = [] ) {
235236
'infoIcon' => constant( 'PROGRESS_PLANNER_URL' ) . '/assets/images/icon_info.svg',
236237
'snoozeIcon' => constant( 'PROGRESS_PLANNER_URL' ) . '/assets/images/icon_snooze.svg',
237238
],
238-
'maxItemsPerCategory' => apply_filters( 'progress_planner_suggested_tasks_max_items_per_category', $max_items_per_category ),
239+
'tasks' => [
240+
'pendingTasks' => $tasks,
241+
'pendingCelebrationTasks' => $pending_celebration_tasks,
242+
'userTasks' => isset( $user_tasks['user'] ) ? $user_tasks['user'] : [],
243+
],
244+
'maxItemsPerCategory' => \progress_planner()->get_suggested_tasks()->get_max_items_per_category(),
239245
'delayCelebration' => $delay_celebration,
240246
],
241247
];

0 commit comments

Comments
 (0)