PluginProbe
Taskbuilder – Project Management & Task Management Tool With Kanban Board / 6.0.6
Taskbuilder – Project Management & Task Management Tool With Kanban Board v6.0.6
6.0.6 6.0.5 6.0.2 6.0.3 6.0.4 6.0.1 6.0.0 5.0.8 5.0.9 4.0.9 5.0.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 All 58 releases
← All changes | includes/admin/projects/open_project/wppm_view_project_tasks.php +788 -66 5.0.46.0.6 View file →
@@ -12,13 +12,60 @@
12 12 $orderby_sql = (sanitize_sql_orderby( "load_order ASC" ));
13 13 $task_status = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wppm_task_statuses ORDER BY $orderby_sql");
14 14 $wppm_task_time = get_option('wppm_task_time');
15 15 $page = isset($_POST['page']) ? sanitize_text_field(wp_unslash($_POST['page'])) : '';
16 +$id = isset($_POST['id']) ? intval(sanitize_text_field(wp_unslash($_POST['id']))) : 0;
17 +$project_id = isset($_POST['project_id']) ? intval(sanitize_text_field(wp_unslash($_POST['project_id']))) : "0";
16 18 $wppm_date_setting = get_option('wppm_date_setting');
17 19 $search_tag = isset($_POST['task_search']) ? sanitize_text_field(wp_unslash($_POST['task_search'])) : '';
18 20 $filter_by = isset($_POST['wppm_task_filter']) ? sanitize_text_field(wp_unslash($_POST['wppm_task_filter'])) : "all";
19 -$proj_filter = isset($_POST['wppm_proj_filter']) ? sanitize_text_field(wp_unslash($_POST['wppm_proj_filter'])) : "0";
21 +$proj_filter = isset($_POST['wppm_proj_filter']) ? absint(wp_unslash($_POST['wppm_proj_filter'])) : "0";
20 22 $public_projects = isset($_POST['public_projects']) ? sanitize_text_field(wp_unslash($_POST['public_projects'])):"0";
23 +/**
24 + * PRIORITIES
25 + */
26 +$priorities = $wpdb->get_results("SELECT id, name FROM {$wpdb->prefix}wppm_task_priorities ORDER BY id ASC");
27 +/**
28 + * USERS
29 + */
30 +$users = get_users(array('orderby' => 'display_name','order' => 'ASC',));
31 +/**
32 + * ASSIGNED USERS
33 + */
34 +$assigned_rows = $wpdb->get_col( "SELECT users FROM {$wpdb->prefix}wppm_task WHERE users IS NOT NULL AND users != ''");
35 +$all_assigned = array();
36 +if (!empty($assigned_rows)) {
37 + foreach ($assigned_rows as $row) {
38 + // Handle comma separated IDs
39 + $ids = explode(',', $row);
40 + foreach ($ids as $uid) {
41 + $uid = absint(trim($uid));
42 + if ($uid > 0) {
43 + $all_assigned[$uid] = $uid;
44 + }
45 + }
46 + }
47 +}
48 +// Final unique IDs
49 +$all_assigned = array_values($all_assigned);
50 +if (isset($_POST['filters'])) {
51 + if (is_string($_POST['filters'])) {
52 + $advanced_filter = json_decode(stripslashes( sanitize_text_field(wp_unslash($_POST['filters']) ) ),true );
53 + } elseif (is_array($_POST['filters'])) {
54 + $raw_filters = wp_unslash($_POST['filters']);
55 + $advanced_filter = [
56 + 'created_by' => array_map('absint', (array) ($raw_filters['created_by'] ?? [])),
57 + 'assigned' => array_map('absint', (array) ($raw_filters['assigned'] ?? [])),
58 + 'priority' => array_map('absint', (array) ($raw_filters['priority'] ?? [])),
59 + 'start_date' => sanitize_text_field($raw_filters['start_date'] ?? ''),
60 + 'end_date' => sanitize_text_field($raw_filters['end_date'] ?? ''),
61 + ];
62 + } else {
63 + $advanced_filter = [];
64 + }
65 +}else{
66 + $advanced_filter = [];
67 +}
21 68 $wppm_current_user_capability = get_user_meta( $current_user->ID, 'wppm_capability', true );
22 69 $wppm_hide_completed_status_task = get_option('wppm_hide_completed_status_task');
23 70 $wppm_hide_task_statuses_from_frontend = get_option('wppm_hide_task_statuses_from_frontend');
24 71 $wppm_deafault_time_duration_task = get_option('wppm_display_time_duration_task');
@@ -33,23 +80,63 @@
33 80 'proj_filter'=>$proj_filter
34 81 );
35 82 $grid_view_filter = $filters ;
36 83 $tl_filters = isset( $_COOKIE['wppm_grid_view_filters'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['wppm_grid_view_filters'] ) ) : $grid_view_filter;
84 +$tl_advanced_filters = [];
85 +if($id != 0){
86 + if ( isset($_COOKIE['tb_kanban_filters']) ) {
87 + $tl_advanced_filters = json_decode(
88 + stripslashes($_COOKIE['tb_kanban_filters']),
89 + true
90 + );
91 + if ( ! is_array($tl_advanced_filters) ) {
92 + $tl_advanced_filters = [];
93 + }
94 + }
95 +}else{
96 + if ( isset($_COOKIE['tb_filters']) ) {
97 + $tl_advanced_filters = json_decode(
98 + stripslashes($_COOKIE['tb_filters']),
99 + true
100 + );
101 + if ( ! is_array($tl_advanced_filters) ) {
102 + $tl_advanced_filters = [];
103 + }
104 + }
105 +}
106 +
107 +//$tl_advanced_filters = isset( $_COOKIE['wppm_advanced_filters'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['wppm_advanced_filters'] ) ) : $tl_advanced_filters;
108 +$filter_values = !empty($advanced_filter)
109 + ? $advanced_filter
110 + : $tl_advanced_filters;
37 111 $current_date = wp_date('Y-m-d');
38 -$proj_attr = isset($_POST['wppm_project_attr']) ? sanitize_text_field(wp_unslash($_POST['wppm_project_attr'])):"";
39 -$archived_where = "";
112 +$proj_attr = isset($_POST['wppm_project_attr']) ? absint(wp_unslash($_POST['wppm_project_attr'])):"";
113 +$archived_where = " AND Task.is_archived = 0";
40 114 if ( isset($page) && $page === 'wppm-archived-tasks' ) {
41 - $archived_where = " AND is_archived = 1";
115 + $archived_where = " AND Task.is_archived = 1";
42 116 }
43 117 if( isset($page) && $page === 'wppm-tasks'){
44 - $archived_where = " AND is_archived = 0";
118 + $archived_where = " AND Task.is_archived = 0";
45 119 }
46 -if(!empty($proj_attr )){
47 - $proj_attr = esc_sql($proj_attr);
48 - $wppm_proj_attr = ' AND (proj.project_name = "'.$proj_attr.'")';
49 -}else{
50 - $wppm_proj_attr = '';
120 +if (!empty($proj_attr)) {
121 + $wppm_proj_attr = $wpdb->prepare(
122 + ' AND proj.project_name = %s',
123 + $proj_attr
124 + );
125 +} else {
126 + $wppm_proj_attr = '';
51 127 }
128 +if ($id != 0 || $project_id != 0) {
129 + $final_project_id = ($project_id != 0) ? intval($project_id) : intval($id);
130 + $wppm_project_filter = $wpdb->prepare(
131 + ' AND Task.project = %d',
132 + $final_project_id
133 + );
134 +} else {
135 +
136 + $wppm_project_filter = '';
137 +}
138 +
52 139 $query = ("SELECT proj.*
53 140 FROM {$wpdb->prefix}wppm_project AS proj
54 141 Left join {$wpdb->prefix}wppm_project_meta proj_meta ON proj.id = proj_meta.project_id");
55 142 $santitize_order_by = esc_sql(sanitize_sql_orderby( "project_name ASC" ));
@@ -55,21 +142,66 @@
55 142 $santitize_order_by = esc_sql(sanitize_sql_orderby( "project_name ASC" ));
56 143 if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin'){
57 144 if(!empty($proj_attr )){
58 145 $proj_attr = esc_sql($proj_attr);
59 - $where = " where project_name = '".$proj_attr."' Group by proj.id ORDER BY '$santitize_order_by'";
146 + $where = $wpdb->prepare(
147 + " WHERE proj.project_name = %s AND proj.is_archived = 0
148 + GROUP BY proj.id
149 + ORDER BY {$santitize_order_by}",
150 + $proj_attr
151 + );
60 152 }else{
61 153 if(!empty($public_projects)){
62 - $where = " where proj.id = proj_meta.project_id AND proj_meta.meta_key='public_project' AND proj_meta.meta_value=1 Group by proj.id ORDER BY '$santitize_order_by'";
154 + $where = $wpdb->prepare(
155 + " WHERE proj.id = proj_meta.project_id
156 + AND proj_meta.meta_key = %s
157 + AND proj_meta.meta_value = %d
158 + AND proj.is_archived = 0
159 + {$wppm_proj_attr}
160 + GROUP BY proj.id
161 + ORDER BY {$santitize_order_by}",
162 + 'public_project',
163 + 1
164 + );
63 165 }else{
64 - $where = " Group by proj.id ORDER BY '$santitize_order_by'";
166 + $where = " WHERE proj.is_archived = 0 GROUP BY proj.id ORDER BY '$santitize_order_by'";
65 167 }
66 168 }
67 169 }else{
68 170 if(!empty($public_projects)){
69 - $where = " where (proj.id = proj_meta.project_id AND proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) $wppm_proj_attr Group by proj.id ORDER BY '$santitize_order_by'";
171 + $where = $wpdb->prepare(
172 + " WHERE (
173 + proj.id = proj_meta.project_id
174 + AND proj_meta.meta_key = %s
175 + AND proj_meta.meta_value = %d
176 + )
177 + {$wppm_proj_attr} AND proj.is_archived = 0
178 + GROUP BY proj.id
179 + ORDER BY {$santitize_order_by}",
180 + 'public_project',
181 + 1
182 + );
70 183 } else{
71 - $where = " where ((FIND_IN_SET($current_user->ID,proj.users)) OR (proj.id = proj_meta.project_id AND proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) OR ( proj.created_by='$cu_id')) $wppm_proj_attr Group by proj.id ORDER BY '$santitize_order_by'";
184 + $where = $wpdb->prepare(
185 + " WHERE (
186 + FIND_IN_SET(%d, proj.users) AND proj.is_archived = 0
187 + OR (
188 + proj.id = proj_meta.project_id
189 + AND proj_meta.meta_key = %s
190 + AND proj_meta.meta_value = %d
191 + )
192 + OR (
193 + proj.created_by = %d
194 + )
195 + )
196 + {$wppm_proj_attr}
197 + GROUP BY proj.id
198 + ORDER BY {$santitize_order_by}",
199 + $current_user->ID,
200 + 'public_project',
201 + 1,
202 + $cu_id
203 + );
72 204 }
73 205 }
74 206 $where = apply_filters('wppm_project_filter_in_task_list_grid_view_where',$where);
75 207 $query.= $where;
@@ -82,9 +214,9 @@
82 214 $tl_filters_arr = $filters;
83 215 }
84 216 $search_tag = isset($_POST['task_search']) ? sanitize_text_field(wp_unslash($_POST['task_search'])) : $tl_filters_arr['search'];
85 217 $filter_by = isset($_POST['wppm_task_filter']) ? sanitize_text_field(wp_unslash($_POST['wppm_task_filter'])) : $tl_filters_arr['filter'];
86 -$proj_filter = isset($_POST['wppm_proj_filter']) ? sanitize_text_field(wp_unslash($_POST['wppm_proj_filter'])) : $tl_filters_arr['proj_filter'];
218 +$proj_filter = isset($_POST['wppm_proj_filter']) ? absint(wp_unslash($_POST['wppm_proj_filter'])) : $tl_filters_arr['proj_filter'];
87 219 $filters = array(
88 220 'search'=>$search_tag,
89 221 'filter'=>$filter_by,
90 222 'proj_filter' =>$proj_filter
@@ -110,10 +242,84 @@
110 242 }elseif($filter_by == 'mine'){
111 243 $wppm_tl_filter = "(FIND_IN_SET('$current_user->ID',Task.users)>0)";
112 244 }elseif($filter_by == 'archived'){
113 245 $wppm_tl_filter = "Task.is_archived = 1";
246 +}elseif($filter_by == 'today'){
247 + $wppm_tl_filter = "DATE(Task.end_date) = CURDATE()";
248 +}elseif($filter_by == 'upcoming'){
249 + $wppm_tl_filter = "DATE(Task.end_date) BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 7 DAY) AND Task.status != 4 AND Task.active = 1 AND Task.is_archived = 0";
250 +}elseif ($filter_by == 'mytasks') {
251 + $wppm_tl_filter = "(
252 + FIND_IN_SET('$current_user->ID', Task.users)
253 + OR Task.created_by = '$current_user->ID'
254 + )
255 + AND Task.status != 4
256 + AND Task.active = 1
257 + AND Task.is_archived = 0";
258 +
114 259 }
115 260
261 +if(!empty($tl_advanced_filters['created_by'])){
262 + $created_by_ids = array_map('intval', $tl_advanced_filters['created_by']);
263 + $wppm_tl_filter .= " AND Task.created_by IN (" . implode(',', $created_by_ids) . ")";
264 +}
265 +if(!empty($tl_advanced_filters['assigned'])){
266 + $assigned_ids = array_map('intval', $tl_advanced_filters['assigned']);
267 + $assigned_sql = [];
268 + foreach ($assigned_ids as $user_id) {
269 + $assigned_sql[] = "FIND_IN_SET('$user_id', Task.users)";
270 + }
271 + $wppm_tl_filter .= " AND (" . implode(' OR ', $assigned_sql) . ")";
272 +}
273 +if(!empty($tl_advanced_filters['priority'])){
274 + $priority = array_map('intval', $tl_advanced_filters['priority']);
275 + $wppm_tl_filter .= " AND Task.priority IN (" . implode(',', $priority) . ")";
276 +}
277 +if(!empty($tl_advanced_filters['start_date'])){
278 + $start_date = sanitize_text_field($tl_advanced_filters['start_date']);
279 + $wppm_tl_filter .= $wpdb->prepare(" AND (CAST(Task.start_date AS DATE)) >= %s", $start_date);
280 +}
281 +if(!empty($tl_advanced_filters['end_date'])){
282 + $end_date = sanitize_text_field($tl_advanced_filters['end_date']);
283 + $wppm_tl_filter .= $wpdb->prepare(" AND (CAST(Task.end_date AS DATE)) <= %s", $end_date);
284 +}
285 +
286 +$advanced_conditions = [];
287 +// Created By
288 +if (!empty($advanced_filter['created_by'])) {
289 + $created_by_ids = array_map('intval', $advanced_filter['created_by']);
290 + $advanced_conditions[] = "Task.created_by IN (" . implode(',', $created_by_ids) . ")";
291 +}
292 +// Assigned Users
293 +if (!empty($advanced_filter['assigned'])) {
294 + $assigned_ids = array_map('intval', $advanced_filter['assigned']);
295 + $assigned_sql = [];
296 + foreach ($assigned_ids as $user_id) {
297 + $assigned_sql[] = "FIND_IN_SET('$user_id', Task.users)";
298 + }
299 + $advanced_conditions[] = "(" . implode(' OR ', $assigned_sql) . ")";
300 +}
301 +// Priority
302 +if (!empty($advanced_filter['priority'])) {
303 + $priority = array_map('intval', $advanced_filter['priority']);
304 + $advanced_conditions[] = "Task.priority IN (" . implode(',', $priority) . ")";
305 +}
306 +// Start Date
307 +if (!empty($advanced_filter['start_date'])) {
308 + $start_date = sanitize_text_field($advanced_filter['start_date']);
309 + $advanced_conditions[] = $wpdb->prepare("(CAST(Task.start_date AS DATE)) >= %s", $start_date);
310 +}
311 +// End Date
312 +if (!empty($advanced_filter['end_date'])) {
313 + $end_date = sanitize_text_field($advanced_filter['end_date']);
314 + $advanced_conditions[] = $wpdb->prepare("(CAST(Task.end_date AS DATE)) <= %s", $end_date);
315 +}
316 +if (!empty($advanced_conditions)) {
317 + $wppm_tl_filter .= " AND " . implode(" AND ", $advanced_conditions);
318 +}
319 +// Subtasks are shown only within their parent task, never as their own row/card in project views.
320 +$wppm_tl_filter .= " AND (Task.parent_task_id = 0 OR Task.parent_task_id IS NULL)";
321 +
116 322 if(!empty($wppm_hide_task_statuses_from_frontend) && is_array($wppm_hide_task_statuses_from_frontend) && (isset($_POST['is_frontend']) && sanitize_text_field($_POST['is_frontend'])==1)){
117 323 foreach($wppm_hide_task_statuses_from_frontend as $status){
118 324 $wppm_tl_filter .= " AND Task.status != '$status'";
119 325 }
@@ -119,15 +325,19 @@
119 325 }
120 326 }
121 327
122 328 if($proj_filter!=0){
123 - $wppm_task_by_proj_filter = "Task.project = ".esc_sql($proj_filter)."";
329 + $proj_filter = absint( $proj_filter );
330 + $wppm_task_by_proj_filter = $wpdb->prepare(
331 + "Task.project = %d AND proj.is_archived = 0",
332 + $proj_filter
333 + );
124 334 }else{
125 335 $wppm_task_by_proj_filter ="1=1";
126 336 }
127 337 if(!empty($task_status)){
128 338 foreach($task_status as $status) {
129 - $status_id = esc_sql($status->id);
339 + $status_id = absint($status->id);
130 340 if(!empty($search_tag)){
131 341 $search_tag_text = '%'.$wpdb->esc_like($search_tag).'%';
132 342 if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin'){
133 343 $query = ("SELECT Task.*
@@ -134,16 +344,56 @@
134 344 FROM {$wpdb->prefix}wppm_task AS Task
135 345 Left join {$wpdb->prefix}wppm_project proj ON Task.project = proj.id
136 346 Left join {$wpdb->prefix}wppm_task_statuses task_statuses ON Task.status = task_statuses.id
137 347 Left join {$wpdb->prefix}wppm_task_priorities task_priorities ON Task.priority = task_priorities.id
138 - Left join {$wpdb->base_prefix}users user ON (FIND_IN_SET(user.id,Task.users)>0) AND user.display_name LIKE '$search_tag_text'
348 + Left join {$wpdb->base_prefix}users user ON (FIND_IN_SET(user.ID,Task.users)>0)
139 349 Left join {$wpdb->prefix}wppm_project_meta proj_meta ON Task.project = proj_meta.project_id
140 350 ");
141 351 $no_of_rows = ( "SELECT count(*) FROM ($query");
142 352 if(!empty($public_projects)){
143 - $where = " where (proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) AND $wppm_tl_filter AND $wppm_task_by_proj_filter AND (Task.task_name LIKE '$search_tag_text' OR proj.project_name LIKE '$search_tag_text' OR task_statuses.name LIKE '$search_tag_text' OR task_priorities.name LIKE '$search_tag_text' OR user.display_name LIKE '$search_tag_text') AND Task.status='$status_id' ";
353 + $where = $wpdb->prepare(
354 + " WHERE (
355 + proj_meta.meta_key = %s
356 + AND proj_meta.meta_value = %d
357 + )
358 + AND {$wppm_tl_filter}
359 + AND {$wppm_task_by_proj_filter}
360 + AND (
361 + Task.task_name LIKE %s
362 + OR proj.project_name LIKE %s
363 + OR task_statuses.name LIKE %s
364 + OR task_priorities.name LIKE %s
365 + OR user.display_name LIKE %s
366 + )
367 + AND Task.status = %d ",
368 + 'public_project',
369 + 1,
370 + $search_tag_text,
371 + $search_tag_text,
372 + $search_tag_text,
373 + $search_tag_text,
374 + $search_tag_text,
375 + $status_id
376 + );
144 377 }else{
145 - $where = " where $wppm_tl_filter AND $wppm_task_by_proj_filter AND (Task.task_name LIKE '$search_tag_text' OR proj.project_name LIKE '$search_tag_text' OR task_statuses.name LIKE '$search_tag_text' OR task_priorities.name LIKE '$search_tag_text' OR user.display_name LIKE '$search_tag_text') AND Task.status='$status_id' ";
378 + $where = $wpdb->prepare(
379 + " WHERE {$wppm_tl_filter}
380 + AND {$wppm_task_by_proj_filter}
381 + AND (
382 + Task.task_name LIKE %s
383 + OR proj.project_name LIKE %s
384 + OR task_statuses.name LIKE %s
385 + OR task_priorities.name LIKE %s
386 + OR user.display_name LIKE %s
387 + )
388 + AND Task.status = %d ",
389 + $search_tag_text,
390 + $search_tag_text,
391 + $search_tag_text,
392 + $search_tag_text,
393 + $search_tag_text,
394 + $status_id
395 + );
146 396 }
147 397 } else{
148 398 $query = ("SELECT Task.*
149 399 FROM {$wpdb->prefix}wppm_task AS Task
@@ -150,16 +400,82 @@
150 400 Left join {$wpdb->prefix}wppm_project proj ON Task.project = proj.id
151 401 Left join {$wpdb->prefix}wppm_task_statuses task_statuses ON Task.status = task_statuses.id
152 402 Left join {$wpdb->prefix}wppm_task_priorities task_priorities ON Task.priority = task_priorities.id
153 403 Left join {$wpdb->prefix}wppm_project_users proj_users ON Task.project = proj_users.proj_id
154 - Left join {$wpdb->base_prefix}users user ON (FIND_IN_SET(user.id,Task.users)>0) AND user.display_name LIKE '$search_tag_text'
404 + Left join {$wpdb->base_prefix}users user ON (FIND_IN_SET(user.ID,Task.users)>0)
155 405 Left join {$wpdb->prefix}wppm_project_meta proj_meta ON Task.project = proj_meta.project_id
156 406 ");
157 407 $no_of_rows = ( "SELECT count(*) FROM ($query");
158 408 if(!empty($public_projects)){
159 - $where = " where (proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) AND $wppm_tl_filter AND $wppm_task_by_proj_filter AND (Task.task_name LIKE '$search_tag_text' OR proj.project_name LIKE '$search_tag_text' OR task_statuses.name LIKE '$search_tag_text' OR task_priorities.name LIKE '$search_tag_text' OR user.display_name LIKE '$search_tag_text')) AND Task.status= '$status_id'";
409 + $where = $wpdb->prepare(
410 + " WHERE (
411 + proj_meta.meta_key = %s
412 + AND proj_meta.meta_value = %d
413 + )
414 + AND proj.is_archived = 0
415 + AND {$wppm_tl_filter}
416 + AND {$wppm_task_by_proj_filter}
417 + AND (
418 + Task.task_name LIKE %s
419 + OR proj.project_name LIKE %s
420 + OR task_statuses.name LIKE %s
421 + OR task_priorities.name LIKE %s
422 + OR user.display_name LIKE %s
423 + )
424 + AND Task.status = %d ",
425 + 'public_project',
426 + 1,
427 + $search_tag_text,
428 + $search_tag_text,
429 + $search_tag_text,
430 + $search_tag_text,
431 + $search_tag_text,
432 + $status_id
433 + );
160 434 }else{
161 - $where = " where $wppm_tl_filter AND $wppm_task_by_proj_filter AND (((FIND_IN_SET('$current_user->ID',Task.users)>0) OR (Task.created_by= '$cu_id') OR (proj_users.user_id = '$cu_id' AND proj_users.role_id = 1 AND (FIND_IN_SET('$current_user->ID',proj.users)>0)) OR (Task.project = proj_meta.project_id AND proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) OR proj.created_by='$cu_id') AND (Task.task_name LIKE '$search_tag_text' OR proj.project_name LIKE '$search_tag_text' OR task_statuses.name LIKE '$search_tag_text' OR task_priorities.name LIKE '$search_tag_text' OR user.display_name LIKE '$search_tag_text')) AND Task.status= '$status_id'";
435 + $where = $wpdb->prepare(
436 + " WHERE {$wppm_tl_filter} AND proj.is_archived = 0
437 + AND {$wppm_task_by_proj_filter}
438 + AND (
439 + (
440 + FIND_IN_SET(%d, Task.users) > 0
441 + OR Task.created_by = %d
442 + OR (
443 + proj_users.user_id = %d
444 + AND proj_users.role_id = %d
445 + AND FIND_IN_SET(%d, proj.users) > 0
446 + )
447 + OR (
448 + Task.project = proj_meta.project_id
449 + AND proj_meta.meta_key = %s
450 + AND proj_meta.meta_value = %d
451 + )
452 + OR proj.created_by = %d
453 + )
454 + AND (
455 + Task.task_name LIKE %s
456 + OR proj.project_name LIKE %s
457 + OR task_statuses.name LIKE %s
458 + OR task_priorities.name LIKE %s
459 + OR user.display_name LIKE %s
460 + )
461 + )
462 + AND Task.status = %d ",
463 + $current_user->ID,
464 + $cu_id,
465 + $cu_id,
466 + 1,
467 + $current_user->ID,
468 + 'public_project',
469 + 1,
470 + $cu_id,
471 + $search_tag_text,
472 + $search_tag_text,
473 + $search_tag_text,
474 + $search_tag_text,
475 + $search_tag_text,
476 + $status_id
477 + );
162 478 }
163 479 }
164 480 }else{
165 481 if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin'){
@@ -168,11 +484,29 @@
168 484 Left join {$wpdb->prefix}wppm_project_meta proj_meta ON Task.project = proj_meta.project_id
169 485 ");
170 486 $no_of_rows = ( "SELECT count(*) FROM ($query");
171 487 if(!empty($public_projects)){
172 - $where = " where (proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) AND $wppm_tl_filter AND $wppm_task_by_proj_filter AND Task.status= '$status_id'";
488 + $where = $wpdb->prepare(
489 + " WHERE (
490 + proj_meta.meta_key = %s
491 + AND proj_meta.meta_value = %d
492 + )
493 + AND {$wppm_tl_filter}
494 + AND proj.is_archived = 0
495 + AND {$wppm_task_by_proj_filter}
496 + AND Task.status = %d ",
497 + 'public_project',
498 + 1,
499 + $status_id
500 + );
173 501 }else{
174 - $where = " where $wppm_tl_filter AND $wppm_task_by_proj_filter AND Task.status= '$status_id'";
502 + $where = $wpdb->prepare(
503 + " WHERE {$wppm_tl_filter}
504 + AND {$wppm_task_by_proj_filter}
505 + AND proj.is_archived = 0
506 + AND Task.status = %d ",
507 + $status_id
508 + );
175 509 }
176 510 }else{
177 511 $query = ( "SELECT Task.*
178 512 FROM {$wpdb->prefix}wppm_task AS Task
@@ -181,11 +515,52 @@
181 515 Left join {$wpdb->prefix}wppm_project_meta proj_meta ON Task.project = proj_meta.project_id
182 516 ");
183 517 $no_of_rows = ( "SELECT count(*) FROM ($query");
184 518 if(!empty($public_projects)){
185 - $where = " where (proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) AND $wppm_tl_filter AND $wppm_task_by_proj_filter AND Task.status= '$status_id'";
519 + $where = $wpdb->prepare(
520 + " WHERE (
521 + proj_meta.meta_key = %s
522 + AND proj_meta.meta_value = %d
523 + )
524 + AND {$wppm_tl_filter}
525 + AND proj.is_archived = 0
526 + AND {$wppm_task_by_proj_filter}
527 + AND Task.status = %d ",
528 + 'public_project',
529 + 1,
530 + $status_id
531 + );
186 532 } else{
187 - $where = " where $wppm_tl_filter AND $wppm_task_by_proj_filter AND ((FIND_IN_SET('$current_user->ID',Task.users)>0) OR (Task.created_by= '$cu_id') OR (proj_users.user_id = '$cu_id' AND proj_users.role_id = 1 AND (FIND_IN_SET('$current_user->ID',proj.users)>0)) OR (Task.project = proj_meta.project_id AND proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) OR proj.created_by='$cu_id') AND Task.status= '$status_id'";
533 + $where = $wpdb->prepare(
534 + " WHERE {$wppm_tl_filter}
535 + AND {$wppm_task_by_proj_filter}
536 + AND proj.is_archived = 0
537 + AND (
538 + FIND_IN_SET(%d, Task.users) > 0
539 + OR Task.created_by = %d
540 + OR (
541 + proj_users.user_id = %d
542 + AND proj_users.role_id = %d
543 + AND FIND_IN_SET(%d, proj.users) > 0
544 + )
545 + OR (
546 + Task.project = proj_meta.project_id
547 + AND proj_meta.meta_key = %s
548 + AND proj_meta.meta_value = %d
549 + )
550 + OR proj.created_by = %d
551 + )
552 + AND Task.status = %d ",
553 + $current_user->ID,
554 + $cu_id,
555 + $cu_id,
556 + 1,
557 + $current_user->ID,
558 + 'public_project',
559 + 1,
560 + $cu_id,
561 + $status_id
562 + );
188 563 }
189 564 }
190 565 }
191 566 $query = apply_filters('wppm_query_for_grid_view',$query);
@@ -193,8 +568,11 @@
193 568 $where.= $wppm_proj_attr;
194 569 if($filter_by != 'archived'){
195 570 $where .= $archived_where;
196 571 }
572 + if($id!=0){
573 + $where .=$wppm_project_filter;
574 + }
197 575 $where = apply_filters('wppm_task_list_where_for_grid_view',$where,$wppm_tl_filter,$search_tag);
198 576 $no_of_rows .= $where;
199 577 $no_of_rows .= " Group by Task.id) AS Task";
200 578 $no_of_rows = apply_filters('wppm_task_list_no_of_rows_for_grid_view',$no_of_rows);
@@ -248,18 +626,25 @@
248 626 $todo_status_style = (!empty($todo_status_name))? "display:inline" :"display:none;";
249 627 $inp_status_style = (!empty($inp_status_name))? "display:inline" :"display:none;";
250 628 $hold_status_style = (!empty($hold_status_name))? "display:inline" :"display:none;";
251 629 $completed_status_style = (!empty($completed_status_name))? "display:inline" :"display:none;";
630 +if ( empty( $id ) ) {
631 + $proj_filter_style = 'display:inline;';
632 +} else {
633 + $proj_filter_style = 'display:none;';
634 +}
252 635 if( isset($page) && $page === 'wppm-tasks'){
253 - $arch_filter_style = "display:inline;";
636 + $arch_filter_style = "display:inline;";
637 + $dashboard_style = "display:inline;";
254 638 }else{
255 - $arch_filter_style = "display:none;";
639 + $arch_filter_style = "display:none;";
640 + $dashboard_style = "display:none;";
256 641 }
257 642
258 643 if ( isset($page) && $page === 'wppm-archived-tasks' ) {
259 - $ar_filter_style = "display:none;";
644 + $arch_filter_style = "display:none;";
260 645 } else {
261 - $ar_filter_style = "display:flex;";
646 + $arch_filter_style = "display:flex;";
262 647 }
263 648 ?>
264 649 <form name="wppm_view_project_task" id="wppm_view_project_task">
265 650 <div class="row">
@@ -271,11 +656,17 @@
271 656 $style = "display:none;";
272 657 }
273 658 $style = apply_filters('wppm_add_new_task_btn_style_grid_view',$style);
274 659 ?>
275 - <span class="wppm-heading-inline"><?php echo (isset($page) && $page === 'wppm-archived-tasks' ) ? esc_html_e('Archived Tasks','taskbuilder'): esc_html_e('Tasks','taskbuilder');?> </span>
276 - <span class="wppm-add-new-btn btn-primary" onclick="wppm_add_new_task()" style="background-color:<?php echo esc_attr($appearance_settings['menu-button-bg-color'])?>;color:<?php echo esc_attr($appearance_settings['menu-button-text-color'])?>;<?php echo esc_attr($style) ?>;"><img class="wppm_add_new_task_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/plus_icon.svg'); ?>" alt="add"><?php echo esc_html_e('Add New','taskbuilder');?></span>
277 - <span class="wppm-add-new-btn btn-primary" style="background-color:<?php echo esc_attr($appearance_settings['menu-button-bg-color'])?>; id="wppm_task_list" onclick="wppm_get_task_list()" ><span><img class="wppm_task_list_image" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/list-symbol.svg'); ?>" alt="list"></span><span style="color:<?php echo esc_attr($appearance_settings['menu-button-text-color'])?>"><?php echo esc_html_e('Task List','taskbuilder');?></span></span>
660 + <span class="wppm-heading-inline" style="<?php echo esc_attr($proj_filter_style);?>"><?php echo (isset($page) && $page === 'wppm-archived-tasks' ) ? esc_html_e('Archived Tasks','taskbuilder'): esc_html_e('Tasks','taskbuilder');?> </span>
661 + <span class="wppm-add-new-btn btn-primary" onclick="wppm_add_new_task('',<?php echo (int)$id; ?>)" style="background-color:<?php echo esc_attr($appearance_settings['menu-button-bg-color'])?>;color:<?php echo esc_attr($appearance_settings['menu-button-text-color'])?>;<?php echo esc_attr($style) ?>;<?php echo esc_attr($proj_filter_style);?>"><img class="wppm_add_new_task_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/plus_icon.svg'); ?>" alt="add"><?php echo esc_html__('Add New','taskbuilder');?></span>
662 + <!-- Dashboard Button -->
663 + <a class="wppm-add-new-btn btn-primary" style="background-color:<?php echo esc_attr($appearance_settings['menu-button-bg-color'])?>;color:<?php echo esc_attr($appearance_settings['menu-button-text-color'])?>;margin-right:3px;!important;<?php echo esc_attr($style)?>;<?php echo esc_attr($proj_filter_style);?>" href="<?php echo esc_url( admin_url('admin.php?page=wppm-dashboard') ); ?>" title="<?php echo esc_attr_e('Go to Dashboard','taskbuilder'); ?>">
664 + <img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/dashboard.svg'); ?>" alt="dashboard_icon">
665 + <?php esc_html_e('Dashboard','taskbuilder'); ?>
666 + </a>
667 + <span class="wppm-add-new-btn btn-primary" style="background-color:<?php echo esc_attr($appearance_settings['menu-button-bg-color'])?>;<?php echo esc_attr($proj_filter_style);?>; id="wppm_task_list" onclick="wppm_get_task_list()" ><span><img class="wppm_task_list_image" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/list-symbol.svg'); ?>" alt="list"></span><span style="color:<?php echo esc_attr($appearance_settings['menu-button-text-color'])?>;<?php echo esc_attr($proj_filter_style);?>"><?php echo esc_html_e('Task List','taskbuilder');?></span></span>
668 + </a></span>
278 669 </div>
279 670 </div>
280 671 <div style="display:flex;justify-content:space-between;margin-top: 20px;flex-wrap: wrap;">
281 672 <div style="display:flex;flex-wrap: wrap;">
@@ -280,27 +671,27 @@
280 671 <div style="display:flex;justify-content:space-between;margin-top: 20px;flex-wrap: wrap;">
281 672 <div style="display:flex;flex-wrap: wrap;">
282 673 <div id="wppm_task_filter_container">
283 674 <div class="wppm-filter-item">
284 - <label for="wppm_task_filter"> <?php echo esc_html_e('Filter','taskbuilder');?></label>
285 - <select id="wppm_task_filter" name="wppm_task_filter" onchange="wppm_apply_task_filter_grid_view('<?php echo esc_attr($page)?>')" class="form-control">
286 - <option value="all"<?php echo ($filter_by == "all")? 'selected':""?>><?php echo esc_html_e('All','taskbuilder');?></option>
287 - <option value="1" style="<?php echo esc_attr($todo_status_style) ?>" <?php echo ($filter_by == "1")? 'selected':""?>><?php echo esc_html($todo_status_name);?></option>
288 - <option value="2" style="<?php echo esc_attr($inp_status_style) ?>" <?php echo ($filter_by == "2")? 'selected':""?>><?php echo esc_html($inp_status_name);?></option>
289 - <option value="3" style="<?php echo esc_attr($hold_status_style) ?>" <?php echo ($filter_by == "3")? 'selected':""?>><?php echo esc_html($hold_status_name);?></option>
290 - <option value="4" style="<?php echo esc_attr($completed_status_style) ?>" <?php echo ($filter_by == "4")? 'selected':""?>><?php echo esc_html($completed_status_name);?></option>
291 - <option value="mine" <?php echo ($filter_by == "mine")? 'selected':""?>><?php echo esc_html_e('Mine','taskbuilder');?></option>
292 - <option value="unassigned" <?php echo ($filter_by == "unassigned")? 'selected':""?>><?php echo esc_html_e('Unassigned','taskbuilder');?></option>
293 - <option value="overdue" <?php echo ($filter_by == "overdue")? 'selected':""?>><?php echo esc_html_e('Overdue','taskbuilder');?></option>
294 - <option value="archived" style="<?php echo esc_attr($arch_filter_style) ?>" <?php echo ($filter_by == "archived")? 'selected':""?>><?php echo esc_html_e('Archived','taskbuilder');?></option>
675 + <label for="wppm_task_filter"> <?php echo esc_html__('Filter','taskbuilder');?></label>
676 + <select id="wppm_task_filter" name="wppm_task_filter" onchange="wppm_apply_task_filter_grid_view('<?php echo esc_attr($page)?>','<?php echo esc_attr($id)?>')" class="form-control">
677 + <option value="all"<?php echo ($filter_by == "all")? 'selected':""?>><?php echo esc_html__('All','taskbuilder');?></option>
678 + <option value="1" style="<?php echo esc_attr($todo_status_style) ?>" <?php echo ($filter_by == "1")? 'selected':""?>><?php echo esc_html__($todo_status_name);?></option>
679 + <option value="2" style="<?php echo esc_attr($inp_status_style) ?>" <?php echo ($filter_by == "2")? 'selected':""?>><?php echo esc_html__($inp_status_name);?></option>
680 + <option value="3" style="<?php echo esc_attr($hold_status_style) ?>" <?php echo ($filter_by == "3")? 'selected':""?>><?php echo esc_html__($hold_status_name);?></option>
681 + <option value="4" style="<?php echo esc_attr($completed_status_style) ?>" <?php echo ($filter_by == "4")? 'selected':""?>><?php echo esc_html__($completed_status_name);?></option>
682 + <option value="mine" <?php echo ($filter_by == "mine")? 'selected':""?>><?php echo esc_html__('Mine','taskbuilder');?></option>
683 + <option value="unassigned" <?php echo ($filter_by == "unassigned")? 'selected':""?>><?php echo esc_html__('Unassigned','taskbuilder');?></option>
684 + <option value="overdue" <?php echo ($filter_by == "overdue")? 'selected':""?>><?php echo esc_html__('Overdue','taskbuilder');?></option>
685 + <option value="archived" style="<?php echo esc_attr($arch_filter_style) ?>" <?php echo ($filter_by == "archived")? 'selected':""?>><?php echo esc_html__('Archived','taskbuilder');?></option>
295 686 </select>
296 687 </div>
297 - <div class="wppm-filter-item wppm_project_autocomplete_container">
688 + <div class="wppm-filter-item wppm_project_autocomplete_container" style="<?php echo esc_attr($proj_filter_style)?>">
298 689 <label for="wppm_task_list_proj_filter">
299 - <?php echo esc_html_e('Project','taskbuilder');?>
690 + <?php echo esc_html__('Project','taskbuilder');?>
300 691 </label><br>
301 692 <select searchable="search here" onchange="wppm_tasks_by_select_project_grid_view('<?php echo esc_attr($page)?>')" class="form-control" size="40" name="wppm_task_list_proj_filter" id="wppm_task_list_proj_filter">
302 - <option value="0" <?php echo ($proj_filter == 0)? 'selected':""?>><?php echo esc_html_e('All','taskbuilder');?></option>
693 + <option value="0" <?php echo ($proj_filter == 0)? 'selected':""?>><?php echo esc_html__('All','taskbuilder');?></option>
303 694 <?php
304 695 if(!empty($projects)){
305 696 foreach($projects as $proj) {
306 697 ?>
@@ -308,22 +699,88 @@
308 699 <?php }
309 700 } ?>
310 701 </select>
311 702 </div>
703 + <!-- FILTER BUTTON -->
704 + <div class="tb-filters" class="wppm-filter-item" style="display:flex;margin-left: 4px;">
705 + <div class="tb-filter-bar">
706 + <span id="tb-advanced-toggle" class="tb-btn" style="margin-bottom: 10px;">
707 + <?php echo esc_html_e('⚙️ Filters', 'taskbuilder'); ?>
708 + </span>
709 + <!-- ACTIVE FILTER CHIPS -->
710 + <div id="tb-active-filters" class="tb-chips"></div>
711 +
712 + <!-- POPOVER -->
713 + <div id="tb-advanced-panel" class="tb-popover">
714 + <div class="tb-mobile-header">
715 + <span><?php echo esc_html_e('Filters', 'taskbuilder'); ?></span>
716 + <button id="tb-close-filters">✕</button>
717 + </div>
718 + <div class="tb-arrow"></div>
719 +
720 + <div class="tb-section">
721 + <h4><?php echo esc_html_e('Created By', 'taskbuilder'); ?></h4>
722 + <select id="tb-created-by" class="form-control" multiple>
723 + <?php
724 + if(!empty($users)){
725 + foreach($users as $user): ?>
726 + <option value="<?php echo esc_attr($user->ID); ?>"><?php echo esc_html($user->display_name); ?></option>
727 + <?php endforeach; }?>
728 + </select>
729 + <h4><?php echo esc_html_e('Assigned To', 'taskbuilder'); ?></h4>
730 + <select id="tb-assigned" multiple>
731 + <?php
732 + if(!empty($all_assigned)){
733 + foreach($all_assigned as $uid){
734 + $user = get_userdata($uid);
735 + if($user){
736 + ?>
737 + <option value="<?php echo esc_attr($uid); ?>">
738 + <?php echo esc_html($user->display_name); ?>
739 + </option>
740 + <?php } }
741 + } ?>
742 + </select>
743 + </div>
744 + <div class="tb-section">
745 + <h4><?php echo esc_html_e('Priority', 'taskbuilder'); ?></h4>
746 + <select id="tb-priority" class="form-control" multiple>
747 + <?php if(!empty($priorities)) {
748 + foreach($priorities as $priority){ ?>
749 + <option value="<?php echo esc_attr($priority->id); ?>">
750 + <?php echo esc_html($priority->name); ?>
751 + </option>
752 + <?php } } ?>
753 + </select>
754 + </div>
755 + <div class="tb-section">
756 + <h4><?php echo esc_html_e('Date', 'taskbuilder'); ?></h4>
757 + <input type="date" class="form-control" id="tb-start-date">
758 + <input type="date" class="form-control"id="tb-end-date">
759 + </div>
760 + <div id="tb-filter-actions">
761 + <button class="wppm-submit-btn" id="tb-apply-filter" type="button"><?php echo esc_html_e('Apply', 'taskbuilder'); ?></button>
762 + <button class="wppm_reset_btn" id="tb-reset-filter" type="button"><?php echo esc_html_e('Reset', 'taskbuilder'); ?></button>
763 + </div>
764 + </div>
765 + </div>
766 + <div id="tb-backdrop"></div>
767 + </div>
312 768 <div class="wppm_display_submit">
313 769 <div class="wppm-filter-actions">
314 - <span class="wppm-link" onclick="wppm_tl_reset_grid_view_filter('<?php echo esc_attr($page)?>')"> <?php echo esc_html_e('Reset','taskbuilder');?></span>
770 + <span class="wppm-link" onclick="wppm_tl_reset_grid_view_filter('<?php echo esc_attr($page)?>',<?php echo esc_attr($id)?>)"> <?php echo esc_html__('Reset','taskbuilder');?></span>
315 771 </div>
316 772 </div>
317 773 </div>
318 774 </div>
319 - <div id="wppm_task_search" style="display:flex;justify-content:flex-end;">
775 + <div id="wppm_task_search" style="display:flex;justify-content:flex-end;margin-left: auto;">
320 776 <img width="25px" height="15" class="wppm_task_search_filter_img" style="position: relative;top: 10px;left: 30px;" height="15px" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/search.svg'); ?>" alt="search">
321 - <input type="search" id="wppm_view_task_search_filter" style="margin-right:10px;" name="wppm_view_task_search_filter" class="form-control form-control-sm" aria-controls="selection-datatable" placeholder="<?php echo esc_attr__('Search','taskbuilder');?>" value="<?php echo (!empty($search_tag)) ? esc_attr($search_tag) : "" ?>">
777 + <input type="search" id="wppm_view_task_search_filter" style="margin-right:10px; min-height:30px!important;" name="wppm_view_task_search_filter" class="form-control form-control-sm" aria-controls="selection-datatable" placeholder="<?php echo esc_attr__('Search','taskbuilder');?>" value="<?php echo (!empty($search_tag)) ? esc_attr($search_tag) : "" ?>">
322 778 </div>
323 779 </div>
780 + <input type="hidden" name="wppm_proj_id" id="wppm_proj_id" value="<?php echo esc_attr($id);?>">
324 781 <div style="display:flex;justify-content:flex-end;margin-right:10px;">
325 - <span id="wppm_list_view_btn" style="margin: 0 0 -30px 0;" onclick="wppm_get_task_list()"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/listv.svg'); ?>" alt="list"><span style="margin-left:5px;"><?php echo esc_html_e('List view','taskbuilder');?></span></span>
782 + <span id="wppm_list_view_btn" style="margin: 5px 0 -30px 0;<?php echo esc_attr($proj_filter_style);?>" onclick="wppm_get_task_list(0,<?php echo esc_attr($id)?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/listv.svg'); ?>" alt="list"><span style="margin-left:5px;"><?php echo esc_html_e('List view','taskbuilder');?></span></span>
326 783 </div>
327 784 <div class="wppm_task_container" id="wppm_task_container" style="display:flex;">
328 785 <?php
329 786 if(!empty($task_status)){
@@ -332,9 +789,9 @@
332 789 <div class="wppm_task_list" id="wppm_task_list_<?php echo esc_attr($status->id)?>" style="display:flex;justify-content:space-between;flex-direction: column;flex-basis: 20%;">
333 790 <div>
334 791 <div style="background-color:<?php echo esc_attr($status->bg_color)?>;color:<?php echo esc_attr($status->color);?>;padding:5px;">
335 792 <span class="wppm_status_name"><?php echo esc_html($status->name);?></span>
336 - <span class="wppm_add_new_icon" onclick="wppm_add_new_task()"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/add_new1.svg'); ?>" alt="add"></span>
793 + <span class="wppm_add_new_icon" onclick="wppm_add_new_task('',<?php echo (int)$id; ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/add_new1.svg'); ?>" alt="add"></span>
337 794 </div>
338 795 </div>
339 796 <div id="wppm_card_body_container_<?php echo esc_attr($status->id) ?>" style="height:100%;">
340 797 <?php
@@ -430,9 +887,9 @@
430 887 )
431 888 );
432 889 $project_data = $wppmfunction->get_project($task->project);
433 890 ?>
434 - <div class="wppm_card_body" style="background-color:<?php echo esc_attr($appearance_settings['grid-background-color'])?>!important;color:<?php echo esc_attr($appearance_settings['grid-header-text-color'])?>!important;" onclick="wppm_open_task(<?php echo esc_attr($task->id)?>)" id="wppm_draggable_card_<?php echo esc_attr($task->id)?>">
891 + <div class="wppm_card_body" style="background-color:<?php echo esc_attr($appearance_settings['grid-background-color'])?>!important;color:<?php echo esc_attr($appearance_settings['grid-header-text-color'])?>!important;" onclick="wppm_open_task(<?php echo esc_attr($task->id)?>,<?php echo esc_attr($id);?>)" id="wppm_draggable_card_<?php echo esc_attr($task->id)?>">
435 892 <div>
436 893 <div>
437 894 <span class="wppm_td_task_priority" style="background-color:<?php echo (!empty($task_priority->bg_color))? esc_attr($task_priority->bg_color):"";?>;color:<?php echo (!empty($task_priority->color))? esc_attr($task_priority->color):"";?>"><?php echo (!empty($task_priority->name))? esc_html($task_priority->name):"" ?></span>
438 895 </div>
@@ -439,10 +896,10 @@
439 896 <div class="wppm_card_task_action">
440 897 <span class="wppm_checklist_total_checked_item"><?php echo esc_html($total_checked_items.'/'.$total)?></span><span class="wppm_total_checked_item"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/checked.svg'); ?>" alt="checked"></span>
441 898 <span class="wppm_show_dropdown_menu" onclick="wppm_show_dropdown_menu(<?php echo esc_attr($task->id);?>)" data-popover="wppm-dropdown-menu-<?php echo esc_attr($task->id);?>" id="wppm_task_action_<?php echo esc_attr($task->id);?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/vertical_dot.svg'); ?>" alt="vertical_dot"></span>
442 899 <div class="gpopover" id="wppm-dropdown-menu-<?php echo esc_attr($task->id);?>">
443 - <a class="dropdown-item" href="#"><?php echo esc_html_e('Edit','taskbuilder');?></a>
444 - <a class="dropdown-item" href="#"><?php echo esc_html_e('Delete','taskbuilder');?></a>
900 + <a class="dropdown-item" href="#"><?php echo esc_html__('Edit','taskbuilder');?></a>
901 + <a class="dropdown-item" href="#"><?php echo esc_html__('Delete','taskbuilder');?></a>
445 902 </div>
446 903 </div>
447 904 </div>
448 905 <div>
@@ -504,9 +961,9 @@
504 961 if($task_per_status==false){
505 962 ?>
506 963 <div>
507 964 <div style="margin-left:5px;font-family: 'OpenSans-Semibold', 'Helvetica Neue', Arial, Helvetica, sans-serif; font-size: 14px;">
508 - <?php echo esc_html_e('Empty','taskbuilder'); ?>
965 + <?php echo esc_html__('Empty','taskbuilder'); ?>
509 966 </div>
510 967 </div>
511 968 <?php
512 969 }
@@ -520,21 +977,21 @@
520 977 <input type="hidden" name="wppm_drag_and_drop_card_ajax_nonce" id="wppm_drag_and_drop_card_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_drag_and_drop_card' ) ); ?>">
521 978 </div>
522 979 <div class="row wppm_task_pagination_container">
523 980 <div class="col-sm-4">
524 - <?php echo esc_html_e('Total:','taskbuilder'); ?>&nbsp;<?php echo esc_html($total_tasks); ?>&nbsp;<?php echo esc_html_e( 'of','taskbuilder') ?>&nbsp;<?php echo esc_html($totalrows_tasks) ?>&nbsp;<?php echo esc_html_e('Tasks','taskbuilder')?>
981 + <?php echo esc_html__('Total:','taskbuilder'); ?>&nbsp;<?php echo esc_html($total_tasks); ?>&nbsp;<?php echo esc_html__('of','taskbuilder') ?>&nbsp;<?php echo esc_html($totalrows_tasks) ?>&nbsp;<?php echo esc_html__('Tasks','taskbuilder')?>
525 982 </div>
526 983 <div class="wppm_task_pagination col-sm-4" style="<?php echo (esc_attr($total_pages)==0)? "display:none;":"display:flex;"?>">
527 984 <span class="wppm-pagination-txt">
528 - <span><?php echo esc_html($current_page)?>&nbsp;<?php echo esc_html_e('of','taskbuilder');?>&nbsp;<?php echo esc_html($total_pages); ?>&nbsp;<?php echo esc_html_e('Page','taskbuilder'); ?></span>
985 + <span><?php echo esc_html($current_page)?>&nbsp;<?php echo esc_html__('of','taskbuilder');?>&nbsp;<?php echo esc_html($total_pages); ?>&nbsp;<?php echo esc_html__('Page','taskbuilder'); ?></span>
529 986 </span>
530 987 <span <?php echo esc_attr($prev_class) ?>
531 988 style="<?php echo (isset($prev_class) && esc_attr($prev_class) == 'disabled') ? 'display:none;':'display:block;'?>cursor:pointer;">
532 - <a class="wppm_pagination_prev" onclick="return wppm_load_prev_task_page_card_view(<?php echo esc_attr($prev_page_no) ?>,<?php echo esc_attr($page_no)?>);"><?php echo esc_html_e('PREV','taskbuilder');?></a>
989 + <a class="wppm_pagination_prev" onclick="return wppm_load_prev_task_page_card_view(<?php echo esc_attr($prev_page_no) ?>,<?php echo esc_attr($page_no)?>);"><?php echo esc_html__('PREV','taskbuilder');?></a>
533 990 </span>
534 991 <span <?php echo esc_attr($next_class) ?>
535 992 style="<?php echo (isset($next_class) && esc_attr($next_class) == 'disabled')?'display:none;':'display:block;'?>cursor:pointer;">
536 - <a class="wppm_pagination_next" onclick="return wppm_load_next_task_page_card_view(<?php echo esc_attr($next_page_no) ?>,<?php echo esc_attr($page_no) ?>);"><?php echo esc_html_e('NEXT','taskbuilder');?></a>
993 + <a class="wppm_pagination_next" onclick="return wppm_load_next_task_page_card_view(<?php echo esc_attr($next_page_no) ?>,<?php echo esc_attr($page_no) ?>);"><?php echo esc_html__('NEXT','taskbuilder');?></a>
537 994 </span>
538 995 </div>
539 996 </div>
540 997 </form>
@@ -564,8 +1021,12 @@
564 1021 .select2-container {
565 1022 max-width: 150px !important;
566 1023 min-width: 150px !important;
567 1024 }
1025 + .select2-selection--multiple {
1026 + max-width: 290px !important;
1027 + min-width: 290px !important;
1028 + }
568 1029 #wppm_task_filter{
569 1030 min-height: 30px !important;
570 1031 max-height: 35px !important;
571 1032 }
@@ -571,10 +1032,29 @@
571 1032 }
572 1033 #wppm_view_project_task .wppm-add-new-btn:hover{
573 1034 background-color: <?php echo esc_attr($appearance_settings['menu-button-hover-color'])?>!important;
574 1035 }
575 -</style>
1036 +</style><?php
1037 +if (!isset($advanced_filter) || !is_array($advanced_filter)) {
1038 + $advanced_filter = [];
1039 +}?>
576 1040 <script type="text/javascript">
1041 + var link = true;
1042 + window.filters = {
1043 + created_by: [],
1044 + assigned: [],
1045 + priority: [],
1046 + start_date: "",
1047 + end_date: "",
1048 + id: null
1049 +};
1050 +
1051 +<?php if (isset($id) && !empty($id)) { ?>
1052 +window.filters.id = <?php echo esc_attr($id); ?>;
1053 +<?php } ?>
1054 +
1055 +var filters = window.filters;
1056 +var wppm_task_filter = <?php echo wp_json_encode($filter_by); ?>;
577 1057 jQuery( document ).ready( function( jQuery ) {
578 1058 dragula([
579 1059 <?php foreach($task_status as $status) { ?>
580 1060 document.getElementById("wppm_card_body_container_<?php echo esc_attr($status->id) ?>"),
@@ -582,14 +1062,191 @@
582 1062 ], {removeOnSpill: false})
583 1063 .on('drop', function (el,target,source) {
584 1064 wppm_drag_drop_card(el,target,source);
585 1065 });
586 -
1066 + var isKanban = <?php echo (isset($id) && !empty($id)) ? 'true' : 'false'; ?>;
1067 + var filterId = isKanban
1068 + ? <?php echo isset($id) ? esc_attr($id) : '0'; ?>
1069 + : 0;
1070 + var filterView = isKanban ? 'kanban' : 'grid';
1071 +
1072 +
1073 + // NOW use isKanban/filterId/filterView
1074 + // SET VALUES AFTER INIT
1075 + let createdBy = <?php echo wp_json_encode(array_map('strval', $filter_values['created_by'] ?? [])); ?>;
1076 +
1077 + let assigned = <?php echo wp_json_encode(array_map('strval', $filter_values['assigned'] ?? [])); ?>;
1078 +
1079 + let priority = <?php echo wp_json_encode(array_map('strval', $filter_values['priority'] ?? [])); ?>;
1080 +
1081 + let startDate = <?php echo wp_json_encode($filter_values['start_date'] ?? ''); ?>;
1082 + let endDate = <?php echo wp_json_encode($filter_values['end_date'] ?? ''); ?>;
1083 +
1084 + filters.created_by = createdBy;
1085 + filters.assigned = assigned;
1086 + filters.priority = priority;
1087 + filters.start_date = startDate;
1088 + filters.end_date = endDate;
1089 +
1090 + if (isKanban) {
1091 + filters.id = filterId;
1092 + } else {
1093 + filters.id = null;
1094 + }
1095 + jQuery('#tb-created-by').val(createdBy).trigger('change');
1096 + jQuery('#tb-assigned').val(assigned).trigger('change');
1097 + jQuery('#tb-priority').val(priority).trigger('change');
1098 +
1099 + jQuery('#tb-start-date').val(startDate);
1100 + jQuery('#tb-end-date').val(endDate);
1101 +
1102 + setTimeout(function() {
1103 + renderActiveFilters(filters);
1104 + }, 300);
1105 + jQuery(document)
1106 + .off("click", "#tb-apply-filter")
1107 + .on("click", "#tb-apply-filter", function (e) {
1108 + e.preventDefault();
1109 + filters.created_by = jQuery("#tb-created-by").val() || [];
1110 + filters.assigned = jQuery("#tb-assigned").val() || [];
1111 + filters.priority = jQuery("#tb-priority").val() || [];
1112 + filters.start_date = jQuery("#tb-start-date").val() || "";
1113 + filters.end_date = jQuery("#tb-end-date").val() || "";
1114 + <?php if (isset($id) && !empty($id)) { ?>
1115 + filters.id = <?php echo esc_attr($id); ?>;
1116 + renderActiveFilters(filters);
1117 + setKanbanFilterCookie(filters);
1118 + triggerFilter(
1119 + 1,
1120 + filters,
1121 + 'kanban',
1122 + <?php echo esc_attr($id); ?>
1123 + );
1124 + <?php } else { ?>
1125 + filters.id = null;
1126 + renderActiveFilters(filters);
1127 + setFilterCookie(filters);
1128 + triggerFilter(
1129 + 1,
1130 + filters,
1131 + 'grid',
1132 + 0
1133 + );
1134 + <?php } ?>
1135 + });
1136 + jQuery(document).on("click", ".tb-remove", function () {
1137 + let key = jQuery(this).attr("data-key");
1138 + let value = jQuery(this).attr("data-value");
1139 + // DATE REMOVE
1140 + if (key === "date") {
1141 + filters.start_date = "";
1142 + filters.end_date = "";
1143 + jQuery("#tb-start-date").val("").trigger("change");
1144 + jQuery("#tb-end-date").val("").trigger("change");
1145 + jQuery(this).closest(".tb-chip").remove();
1146 + syncUIWithFilters(filters);
1147 + renderActiveFilters(filters);
1148 + <?php if (isset($id) && !empty($id)) { ?>
1149 + filters.id = <?php echo esc_attr($id); ?>;
1150 + syncUIWithFilters(filters);
1151 + renderActiveFilters(filters);
1152 + setKanbanFilterCookie(filters);
1153 + triggerFilter(
1154 + 1,
1155 + filters,
1156 + 'kanban',
1157 + <?php echo esc_attr($id); ?>
1158 + );
1159 + <?php } else { ?>
1160 + filters.id = null;
1161 + syncUIWithFilters(filters);
1162 + renderActiveFilters(filters);
1163 + setFilterCookie(filters);
1164 + triggerFilter(
1165 + 1,
1166 + filters,
1167 + 'grid',
1168 + 0
1169 + );
1170 + <?php } ?>
1171 + return;
1172 + }
1173 + // REMOVE CREATED BY / ASSIGNED / PRIORITY
1174 + else {
1175 + filters[key] = (filters[key] || [])
1176 + .map(String)
1177 + .filter(v => v !== String(value));
1178 + jQuery(`#tb-${key}`)
1179 + .val(filters[key])
1180 + .trigger("change");
1181 + // Remove chip
1182 + jQuery(this).closest(".tb-chip").remove();
1183 + // Sync UI
1184 + syncUIWithFilters(filters);
1185 + // Render active filters
1186 + renderActiveFilters(filters);
1187 + <?php if (isset($id) && !empty($id)) { ?>
1188 + filters.id = <?php echo esc_attr($id); ?>;
1189 + syncUIWithFilters(filters);
1190 + renderActiveFilters(filters);
1191 + setKanbanFilterCookie(filters);
1192 + triggerFilter(
1193 + 1,
1194 + filters,
1195 + 'kanban',
1196 + <?php echo esc_attr($id); ?>
1197 + );
1198 + <?php } else { ?>
1199 + filters.id = null;
1200 + syncUIWithFilters(filters);
1201 + renderActiveFilters(filters);
1202 + setFilterCookie(filters);
1203 + triggerFilter(
1204 + 1,
1205 + filters,
1206 + 'grid',
1207 + 0
1208 + );
1209 + <?php } ?>
1210 + }
1211 + });
1212 + jQuery(document)
1213 + .off("click", "#tb-reset-filter")
1214 + .on("click", "#tb-reset-filter", function () {
1215 + window.filters = {
1216 + created_by: [],
1217 + assigned: [],
1218 + priority: [],
1219 + start_date: "",
1220 + end_date: "",
1221 + id: isKanban ? filterId : null
1222 + };
1223 + filters = window.filters;
1224 + syncUIWithFilters(filters);
1225 + jQuery("#tb-active-filters").html("");
1226 + if (isKanban) {
1227 + syncUIWithFilters(filters);
1228 + renderActiveFilters(filters);
1229 + setKanbanFilterCookie(filters);
1230 + } else {
1231 + syncUIWithFilters(filters);
1232 + renderActiveFilters(filters);
1233 + setFilterCookie(filters);
1234 + }
1235 + triggerFilter(
1236 + 1,
1237 + filters,
1238 + filterView,
1239 + filterId
1240 + );
1241 + jQuery("#tb-advanced-panel").removeClass("tb-open");
1242 + jQuery("#tb-backdrop").removeClass("active");
1243 + });
587 1244 jQuery("input[name='wppm_view_task_search_filter']").keypress(function(e) {
588 1245 //Enter key
589 1246 if (e.which == 13) {
590 1247 e.preventDefault();
591 - wppm_display_grid_view('<?php echo esc_js($page) ?>');
1248 + wppm_display_grid_view('<?php echo esc_js($page) ?>','<?php echo esc_js($id) ?>');
592 1249 }
593 1250 });
594 1251 })
595 1252 function wppm_show_dropdown_menu(task_id){
@@ -604,11 +1261,76 @@
604 1261 source:source.id,
605 1262 _ajax_nonce:jQuery("#wppm_drag_and_drop_card_ajax_nonce").val()
606 1263 };
607 1264 jQuery.post(wppm_admin.ajax_url, data, function(response) {
608 - wppm_display_grid_view('<?php echo esc_js($page) ?>');
1265 + wppm_display_grid_view('<?php echo esc_js($page) ?>','<?php echo esc_js($id) ?>');
609 1266 });
610 1267 }
1268 + function wppm_tl_reset_grid_view_filter(page,id){
1269 + var url = new URL(window.location.href);
1270 + if (url.searchParams.has('wppm_task_filter')) {
1271 + url.searchParams.delete('wppm_task_filter');
1272 + window.location.href = url.toString();
1273 + return false;
1274 + }
1275 + jQuery('#wppm_task_container').html(wppm_admin.loading_html);
1276 + var data = {
1277 + action: 'wppm_view_project_tasks',
1278 + wppm_task_filter:'all',
1279 + task_search:"",
1280 + sort_by:"task_name",
1281 + order:"ASC",
1282 + wppm_proj_filter:"0",
1283 + page:page,
1284 + id:id
1285 + };
1286 + jQuery.post(wppm_admin.ajax_url, data, function(response) {
1287 + jQuery('#wppm_task_container').html(response);
1288 + });
1289 + // ✅ close popup
1290 + jQuery("#tb-advanced-panel").removeClass("tb-open");
1291 + jQuery("#tb-backdrop").removeClass("active");
1292 +
1293 + // ✅ clear inputs
1294 + jQuery('#tb-advanced-panel input').val('');
1295 + jQuery('#tb-advanced-panel select').val([]);
1296 +
1297 + // ✅ clear chips
1298 + jQuery("#tb-active-filters").html('');
1299 + if(id!=0){
1300 + resetFilters('kanban');
1301 + }else{
1302 + resetFilters('grid');
1303 + }
1304 + }
611 1305 jQuery('#wppm_task_list_proj_filter').select2({ dropdownAutoWidth: true, width: 'auto' });
612 1306 jQuery('#wppm_task_list_proj_filter').val(<?php echo esc_attr($proj_filter) ?>);
1307 + jQuery('#tb-created-by').select2({ dropdownAutoWidth: true, width: '100%'});
1308 + jQuery('#tb-created-by').val(<?php echo wp_json_encode($filter_values['created_by'] ?? []); ?>).trigger('change');
1309 + jQuery('#tb-assigned').select2({ dropdownAutoWidth: true, width: '100%' });
1310 + jQuery('#tb-assigned').val(<?php echo wp_json_encode($filter_values['assigned'] ?? []); ?>).trigger('change');
1311 + jQuery('#tb-priority').select2({dropdownAutoWidth: true, width: '100%'});
1312 + jQuery('#tb-priority').val(<?php echo wp_json_encode($filter_values['priority'] ?? []); ?>).trigger('change');
1313 + jQuery(document).off("click", "#tb-advanced-toggle").on("click", "#tb-advanced-toggle", function (e) {
1314 + e.stopPropagation();
1315 + jQuery("#tb-advanced-panel").toggleClass("tb-open");
1316 + });
1317 +
1318 + /* Close on backdrop click */
1319 + jQuery(document).on("click", "#tb-backdrop", function () {
1320 + jQuery("#tb-advanced-panel").removeClass("tb-open");
1321 + jQuery(this).removeClass("active");
1322 + });
1323 +
1324 + /* Close on outside (desktop only) */
1325 + jQuery(document).on("click", function (e) {
1326 + if (window.innerWidth > 768) {
1327 + if (!jQuery(e.target).closest("#tb-advanced-panel, #tb-advanced-toggle").length) {
1328 + jQuery("#tb-advanced-panel").removeClass("tb-open");
1329 + }
1330 + }
1331 + });jQuery(document).on("click", "#tb-close-filters", function () {
1332 + jQuery("#tb-advanced-panel").removeClass("tb-open");
1333 + jQuery("#tb-backdrop").removeClass("active");
1334 + });
613 1335
614 1336 </script>