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/tasks/wppm_tasks_list.php +727 -147 5.0.26.0.6 View file →
@@ -3,17 +3,54 @@
3 3 exit; // Exit if accessed directly
4 4 }
5 5 global $current_user,$wpdb,$wppmfunction;
6 6 $task_per_page = 20;
7 -$page_no = isset($_POST['page_no']) ? intval(sanitize_text_field($_POST['page_no'])): '0';
8 -$search_tag = isset($_POST['task_search']) ? sanitize_text_field($_POST['task_search']) : '';
9 -$order = isset($_POST['order']) ? sanitize_text_field($_POST['order']) :"ASC";
10 -$sort_by = isset($_POST['sort_by']) ? sanitize_text_field($_POST['sort_by']):"task_name";
11 -$filter_by = isset($_POST['wppm_task_filter']) ? sanitize_text_field($_POST['wppm_task_filter']) : "all";
12 -$proj_filter = isset($_POST['wppm_proj_filter']) ? sanitize_text_field($_POST['wppm_proj_filter']) : "0";
13 -$proj_attr = isset($_POST['wppm_project_attr']) ? sanitize_text_field($_POST['wppm_project_attr']):"";
14 -$public_projects = isset($_POST['public_projects']) ? sanitize_text_field($_POST['public_projects']):"0";
15 -$page = isset($_POST['page']) ? sanitize_text_field($_POST['page']):"";
7 +$page_no = isset($_POST['page_no']) ? intval(sanitize_text_field(wp_unslash($_POST['page_no']))) : '0';
8 +$project_id = isset($_POST['project_id']) ? intval(sanitize_text_field(wp_unslash($_POST['project_id']))) : "0";
9 +$search_tag = isset($_POST['task_search']) ? sanitize_text_field(wp_unslash($_POST['task_search'])) : '';
10 +$order = isset($_POST['order']) ? sanitize_text_field(wp_unslash($_POST['order'])) :"ASC";
11 +$sort_by = isset($_POST['sort_by']) ? sanitize_text_field(wp_unslash($_POST['sort_by'])):"task_name";
12 +$filter_by = isset($_POST['wppm_task_filter']) ? sanitize_text_field(wp_unslash($_POST['wppm_task_filter'])) : "all";
13 +if (isset($_POST['filters'])) {
14 + if (is_string($_POST['filters'])) {
15 + $advanced_filter = json_decode( stripslashes( sanitize_text_field( wp_unslash($_POST['filters']))),true );
16 + } elseif (is_array($_POST['filters'])) {
17 + $raw_filters = wp_unslash($_POST['filters']);
18 + $advanced_filter = [
19 + 'created_by' => array_map('absint', (array) ($raw_filters['created_by'] ?? [])),
20 + 'assigned' => array_map('absint', (array) ($raw_filters['assigned'] ?? [])),
21 + 'priority' => array_map('absint', (array) ($raw_filters['priority'] ?? [])),
22 + 'start_date' => sanitize_text_field($raw_filters['start_date'] ?? ''),
23 + 'end_date' => sanitize_text_field($raw_filters['end_date'] ?? ''),
24 + ];
25 + } else {
26 + $advanced_filter = [];
27 + }
28 +}else{
29 + $advanced_filter = [];
30 +}
31 +///$advanced_filter = isset($_POST['filters']) ? (($_POST['filters'])) : "array()";
32 +$proj_filter = isset($_POST['wppm_proj_filter']) ? sanitize_text_field(wp_unslash($_POST['wppm_proj_filter'])) : "0";
33 +$proj_attr = isset($_POST['wppm_project_attr']) ? sanitize_text_field(wp_unslash($_POST['wppm_project_attr'])):"";
34 +$public_projects = isset($_POST['public_projects']) ? sanitize_text_field(wp_unslash($_POST['public_projects'])):"0";
35 +$tb_start_date = isset($_POST['tb_start_date']) ? sanitize_text_field($_POST['tb_start_date']) : '';
36 +$tb_end_date = isset($_POST['tb_end_date']) ? sanitize_text_field($_POST['tb_end_date']) : '';
37 +$tb_created_by = isset($_POST['tb_created_by']) ? sanitize_text_field($_POST['tb_created_by']) : '';
38 +$page = isset($_POST['page']) ? sanitize_text_field(wp_unslash($_POST['page'])):"";
39 +$priorities = $wpdb->get_results("SELECT id, name FROM {$wpdb->prefix}wppm_task_priorities ORDER BY id ASC ");
40 +$users = get_users(array(
41 + 'orderby' => 'display_name',
42 + 'order' => 'ASC'
43 +));
44 +$assigned_users = $wpdb->get_col( " SELECT DISTINCT users FROM {$wpdb->prefix}wppm_task WHERE users != ''");
45 +$all_assigned = [];
46 +foreach ($assigned_users as $row) {
47 + $ids = explode(',', $row);
48 + foreach ($ids as $id) {
49 + $all_assigned[] = trim($id);
50 + }
51 +}
52 +$all_assigned = array_unique($all_assigned);
16 53 $wppm_current_user_capability = get_user_meta( $current_user->ID, 'wppm_capability', true );
17 54 $wppm_create_tasks_coworkers_permission = get_option('wppm_allow_coworkers_create_task');
18 55 $orderby_proj_sql = esc_sql(sanitize_sql_orderby( "project_name" ));
19 56 $wppm_date_setting = get_option('wppm_date_setting');
@@ -18,8 +55,9 @@
18 55 $orderby_proj_sql = esc_sql(sanitize_sql_orderby( "project_name" ));
19 56 $wppm_date_setting = get_option('wppm_date_setting');
20 57 $wppm_hide_completed_status_task = get_option('wppm_hide_completed_status_task');
21 58 $wppm_hide_task_statuses_from_frontend = get_option('wppm_hide_task_statuses_from_frontend');
59 +$wppm_deafault_time_duration_task = get_option('wppm_display_time_duration_task');
22 60 if(!empty($wppm_hide_task_statuses_from_frontend)){
23 61 $wppm_hide_task_statuses_from_frontend = explode(",",$wppm_hide_task_statuses_from_frontend);
24 62 } else {
25 63 $wppm_hide_task_statuses_from_frontend = '';
@@ -25,44 +63,84 @@
25 63 $wppm_hide_task_statuses_from_frontend = '';
26 64 }
27 65 $proj_attr = esc_sql($proj_attr);
28 66 $is_frontend = 0;
29 -if(!empty($proj_attr )){
30 - $wppm_proj_attr = ' AND (proj.project_name = "'.$proj_attr.'")';
31 -}else{
32 - $wppm_proj_attr = '';
67 +if ( ! empty( $proj_attr ) ) {
68 + $wppm_proj_attr = $wpdb->prepare(
69 + ' AND (proj.project_name = %s)',
70 + $proj_attr
71 + );
72 +} else {
73 + $wppm_proj_attr = '';
33 74 }
34 -$current_date = date('Y-m-d');
75 +$current_date = wp_date('Y-m-d');
35 76 $current_date = esc_sql($current_date );
36 77 $cu_id = esc_sql($current_user->ID);
37 -$archived_where = "";
38 -if ( isset($page) && $page === 'wppm-archived-tasks' ) {
39 - $archived_where = " AND is_archived = 1";
78 +$archived_where = '';
79 +if ( isset( $page ) && $page === 'wppm-archived-tasks' ) {
80 + $archived_where = ' AND Task.is_archived = 1';
81 +} elseif ( isset( $page ) && $page === 'wppm-tasks' ) {
82 + $archived_where = ' AND Task.is_archived = 0';
40 83 }
41 -if( isset($page) && $page === 'wppm-tasks'){
42 - $archived_where = " AND is_archived = 0";
43 -}
44 84 $wppm_task_time = get_option('wppm_task_time');
45 -$query = ("SELECT proj.*
46 - FROM {$wpdb->prefix}wppm_project AS proj
47 - Left join {$wpdb->prefix}wppm_project_meta proj_meta ON proj.id = proj_meta.project_id");
48 -if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin'){
49 - if(!empty($proj_attr )){
50 - $where = " where project_name = '".$proj_attr."' Group by proj.id ORDER BY ".$orderby_proj_sql;
51 - }else{
52 - if(!empty($public_projects)){
53 - $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 ".$orderby_proj_sql;
54 - }else{
55 - $where = " Group by proj.id ORDER BY ".$orderby_proj_sql;
85 +$query = "SELECT proj.*
86 +FROM {$wpdb->prefix}wppm_project AS proj
87 +LEFT JOIN {$wpdb->prefix}wppm_project_meta AS proj_meta ON proj.id = proj_meta.project_id";
88 +if ( $current_user->has_cap( 'manage_options' ) || $wppm_current_user_capability === 'wppm_admin' ) {
89 + if ( ! empty( $proj_attr ) ) {
90 + $where = $wpdb->prepare(
91 + " WHERE proj.project_name = %s
92 + GROUP BY proj.id
93 + ORDER BY $orderby_proj_sql",
94 + $proj_attr
95 + );
96 + } else {
97 + if ( ! empty( $public_projects ) ) {
98 + $where = $wpdb->prepare(
99 + " WHERE proj_meta.meta_key = %s
100 + AND proj_meta.meta_value = %d
101 + GROUP BY proj.id
102 + ORDER BY $orderby_proj_sql",
103 + 'public_project',
104 + 1
105 + );
106 + } else {
107 + $where = " GROUP BY proj.id ORDER BY $orderby_proj_sql";
108 + }
56 109 }
57 - }
58 -}else{
59 - if(!empty($public_projects)){
60 - $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 $orderby_proj_sql";
61 - }
62 - else{
63 - $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 $orderby_proj_sql";
64 - }
110 +} else {
111 + if ( ! empty( $public_projects ) ) {
112 + $where = $wpdb->prepare(
113 + " WHERE (
114 + proj_meta.meta_key = %s
115 + AND proj_meta.meta_value = %d
116 + )
117 + $wppm_proj_attr
118 + GROUP BY proj.id
119 + ORDER BY $orderby_proj_sql",
120 + 'public_project',
121 + 1
122 + );
123 +
124 + } else {
125 + $where = $wpdb->prepare(
126 + " WHERE (
127 + FIND_IN_SET(%d, proj.users)
128 + OR (
129 + proj_meta.meta_key = %s
130 + AND proj_meta.meta_value = %d
131 + )
132 + OR proj.created_by = %d
133 + )
134 + $wppm_proj_attr
135 + GROUP BY proj.id
136 + ORDER BY $orderby_proj_sql",
137 + $current_user->ID,
138 + 'public_project',
139 + 1,
140 + $cu_id
141 + );
142 + }
65 143 }
66 144 $where = apply_filters('wppm_project_filter_in_task_list_where',$where);
67 145 $query.= $where;
68 146 $projects = $wpdb->get_results($query);
@@ -74,8 +152,20 @@
74 152 'filter'=>$filter_by,
75 153 'proj_filter' =>$proj_filter
76 154 );
77 155 $tl_filters = isset( $_COOKIE['wppm_filters'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['wppm_filters'] ) ) : $filters;
156 +$tl_advanced_filters = [];
157 +if ( !empty($_COOKIE['tb_list_filters']) ) {
158 + $tl_advanced_filters = json_decode(
159 + stripslashes($_COOKIE['tb_list_filters']),
160 + true
161 + );
162 + if ( ! is_array($tl_advanced_filters) ) {
163 + $tl_advanced_filters = [];
164 + }
165 +}
166 +//$tl_advanced_filters = isset( $_COOKIE['wppm_advanced_filters'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['wppm_advanced_filters'] ) ) : $tl_advanced_filters;
167 +
78 168 if(!is_array($tl_filters)){
79 169 $tl_filters = json_decode($tl_filters);
80 170 $tl_filters_arr = (array) $tl_filters;
81 171 } else{
@@ -81,13 +171,13 @@
81 171 } else{
82 172 $tl_filters_arr = $filters;
83 173 }
84 174 $wppm_tl_filter = "1=1";
85 -$order = isset($_POST['order']) ? sanitize_text_field($_POST['order']) :$tl_filters_arr['order'];
86 -$sort_by = isset($_POST['sort_by']) ? sanitize_text_field($_POST['sort_by']):$tl_filters_arr['sort_by'];
87 -$search_tag = isset($_POST['task_search']) ? sanitize_text_field($_POST['task_search']) : $tl_filters_arr['search'];
88 -$filter_by = isset($_POST['wppm_task_filter']) ? sanitize_text_field($_POST['wppm_task_filter']) : $tl_filters_arr['filter'];
89 -$proj_filter = isset($_POST['wppm_proj_filter']) ? sanitize_text_field($_POST['wppm_proj_filter']) : $tl_filters_arr['proj_filter'];
175 +$order = isset($_POST['order']) ? sanitize_text_field(wp_unslash($_POST['order'])) :$tl_filters_arr['order'];
176 +$sort_by = isset($_POST['sort_by']) ? sanitize_text_field(wp_unslash($_POST['sort_by'])):$tl_filters_arr['sort_by'];
177 +$search_tag = isset($_POST['task_search']) ? sanitize_text_field(wp_unslash($_POST['task_search'])) : $tl_filters_arr['search'];
178 +$filter_by = isset($_POST['wppm_task_filter']) ? sanitize_text_field(wp_unslash($_POST['wppm_task_filter'])) : $tl_filters_arr['filter'];
179 +$proj_filter = isset($_POST['wppm_proj_filter']) ? sanitize_text_field(wp_unslash($_POST['wppm_proj_filter'])) : $tl_filters_arr['proj_filter'];
90 180 $proj_filter = esc_sql($proj_filter);
91 181 if($sort_by == ""){
92 182 $sort_by = 'task_name';
93 183 }
@@ -98,24 +188,30 @@
98 188 'filter'=>$filter_by,
99 189 'proj_filter'=>$proj_filter
100 190 );
101 191 setcookie('wppm_filters',wp_json_encode( $filters ),time() + 3600);
192 +//setcookie('wppm_advanced_filters',wp_json_encode( $tl_advanced_filters ),time() + 3600);
193 +// Allowed sort columns
194 +$allowed_sort_by = [
195 + 'project' => 'proj.project_name',
196 + 'status' => 'task_statuses.name',
197 + 'priority' => 'task_priorities.name',
198 + 'start_date' => 'Task.start_date',
199 + 'end_date' => 'Task.end_date',
200 + 'TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)' => 'TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)',
201 +];
102 202
103 -if($tl_filters_arr['sort_by']=='project'){
104 - $sort_by = 'proj.project_name';
105 -}
106 -if($tl_filters_arr['sort_by']=='start_date'){
107 - $sort_by = 'Task.start_date';
108 -}
109 -if($tl_filters_arr['sort_by']=='end_date'){
110 - $sort_by = 'Task.end_date';
111 -}
112 -if($tl_filters_arr['sort_by']=='status'){
113 - $sort_by = 'task_statuses.name';
114 -}
115 -if($tl_filters_arr['sort_by']=='priority'){
116 - $sort_by='task_priorities.name';
117 -}
203 +// Resolve sort_by safely
204 +$sort_key = isset($_POST['sort_by'])
205 + ? sanitize_text_field(wp_unslash($_POST['sort_by']))
206 + : ($tl_filters_arr['sort_by'] ?? 'task_name');
207 +
208 +$sort_by = $allowed_sort_by[$sort_key] ?? 'Task.task_name';
209 +// Resolve order safely
210 +$order = (isset($_POST['order']) && strtoupper(wp_unslash($_POST['order'])) === 'ASC')
211 + ? 'ASC'
212 + : 'DESC';
213 +
118 214 if($filter_by=='all'){
119 215 if($wppm_hide_completed_status_task == 0){
120 216 $wppm_tl_filter = "Task.status!='4'";
121 217 }
@@ -135,22 +231,103 @@
135 231 }elseif($filter_by == 'mine'){
136 232 $wppm_tl_filter = "(FIND_IN_SET('$current_user->ID',Task.users)>0)";
137 233 }elseif($filter_by == 'archived'){
138 234 $wppm_tl_filter = "Task.is_archived = 1";
235 +} elseif($filter_by == 'today'){
236 + $wppm_tl_filter = "DATE(Task.end_date) = CURDATE()";
237 +}elseif($filter_by == 'upcoming'){
238 + $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";
239 +}elseif ($filter_by == 'mytasks') {
240 + $wppm_tl_filter = "(
241 + FIND_IN_SET('$current_user->ID', Task.users)
242 + OR Task.created_by = '$current_user->ID'
243 + )
244 + AND Task.status != 4
245 + AND Task.active = 1
246 + AND Task.is_archived = 0";
247 +
139 248 }
140 249
141 -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))){
250 +if(!empty($tl_advanced_filters['created_by'])){
251 + $created_by_ids = array_map('intval', $tl_advanced_filters['created_by']);
252 + $wppm_tl_filter .= " AND Task.created_by IN (" . implode(',', $created_by_ids) . ")";
253 +}
254 +if(!empty($tl_advanced_filters['assigned'])){
255 + $assigned_ids = array_map('intval', $tl_advanced_filters['assigned']);
256 + $assigned_sql = [];
257 + foreach ($assigned_ids as $id) {
258 + $assigned_sql[] = "FIND_IN_SET('$id', Task.users)";
259 + }
260 + $wppm_tl_filter .= " AND (" . implode(' OR ', $assigned_sql) . ")";
261 +}
262 +if(!empty($tl_advanced_filters['priority'])){
263 + $priority = array_map('intval', $tl_advanced_filters['priority']);
264 + $wppm_tl_filter .= " AND Task.priority IN (" . implode(',', $priority) . ")";
265 +}
266 +if(!empty($tl_advanced_filters['start_date'])){
267 + $start_date = sanitize_text_field($tl_advanced_filters['start_date']);
268 + $wppm_tl_filter .= $wpdb->prepare(" AND (CAST(Task.start_date AS DATE)) >= %s", $start_date);
269 +}
270 +if(!empty($tl_advanced_filters['end_date'])){
271 + $end_date = sanitize_text_field($tl_advanced_filters['end_date']);
272 + $wppm_tl_filter .= $wpdb->prepare(" AND (CAST(Task.end_date AS DATE)) <= %s", $end_date);
273 +}
274 +
275 +$advanced_conditions = [];
276 +// Created By
277 +if (!empty($advanced_filter['created_by'])) {
278 + $created_by_ids = array_map('intval', $advanced_filter['created_by']);
279 + $advanced_conditions[] = "Task.created_by IN (" . implode(',', $created_by_ids) . ")";
280 +}
281 +// Assigned Users
282 +if (!empty($advanced_filter['assigned'])) {
283 + $assigned_ids = array_map('intval', $advanced_filter['assigned']);
284 + $assigned_sql = [];
285 + foreach ($assigned_ids as $id) {
286 + $assigned_sql[] = "FIND_IN_SET('$id', Task.users)";
287 + }
288 + $advanced_conditions[] = "(" . implode(' OR ', $assigned_sql) . ")";
289 +}
290 +// Priority
291 +if (!empty($advanced_filter['priority'])) {
292 + $priority = array_map('intval', $advanced_filter['priority']);
293 + $advanced_conditions[] = "Task.priority IN (" . implode(',', $priority) . ")";
294 +}
295 +// Start Date
296 +if (!empty($advanced_filter['start_date'])) {
297 + $start_date = sanitize_text_field($advanced_filter['start_date']);
298 + $advanced_conditions[] = $wpdb->prepare("(CAST(Task.start_date AS DATE)) >= %s", $start_date);
299 +}
300 +// End Date
301 +if (!empty($advanced_filter['end_date'])) {
302 + $end_date = sanitize_text_field($advanced_filter['end_date']);
303 + $advanced_conditions[] = $wpdb->prepare("(CAST(Task.end_date AS DATE)) <= %s", $end_date);
304 +}
305 +if (!empty($advanced_conditions)) {
306 + $wppm_tl_filter .= " AND " . implode(" AND ", $advanced_conditions);
307 +}
308 +// Subtasks are shown only within their parent task, never as their own row in the task list.
309 +$wppm_tl_filter .= " AND (Task.parent_task_id = 0 OR Task.parent_task_id IS NULL)";
310 +//setcookie('wppm_advanced_filters',wp_json_encode( $advanced_filter ),time() + 3600);
311 +if(!empty($wppm_hide_task_statuses_from_frontend) && is_array($wppm_hide_task_statuses_from_frontend) && ((isset($_POST['is_frontend'])) && (sanitize_text_field(wp_unslash($_POST['is_frontend']))==1))){
142 312 foreach($wppm_hide_task_statuses_from_frontend as $status){
143 313 $wppm_tl_filter .= " AND Task.status != '$status'";
144 314 }
145 315 }
146 -if($proj_filter!=0){
147 - $wppm_task_by_proj_filter = "Task.project = '$proj_filter'";
148 -}else{
149 - $wppm_task_by_proj_filter ="1=1";
316 +if ( $proj_filter != 0 || $project_id != 0 ) {
317 + if ( $project_id != 0 ) {
318 + $proj_filter = $project_id;
319 + }
320 + $proj_filter = absint( $proj_filter );
321 + $wppm_task_by_proj_filter = $wpdb->prepare(
322 + "Task.project = %d",
323 + $proj_filter
324 + );
325 +} else {
326 + $wppm_task_by_proj_filter = "1=1";
150 327 }
151 328 $wppm_default_task_date = get_option('wppm_default_task_date');
152 -$search_tag_text = '%'.$wpdb->esc_like($search_tag).'%';
329 +$search_tag_text = "";
153 330 if(!empty($search_tag)){
154 331 $search_tag_text = '%'.$wpdb->esc_like($search_tag).'%';
155 332 $query = ("SELECT Task.*
156 333 FROM {$wpdb->prefix}wppm_task AS Task
@@ -157,9 +334,9 @@
157 334 Left join {$wpdb->prefix}wppm_project proj ON Task.project = proj.id
158 335 Left join {$wpdb->prefix}wppm_task_statuses task_statuses ON Task.status = task_statuses.id
159 336 Left join {$wpdb->prefix}wppm_task_priorities task_priorities ON Task.priority = task_priorities.id
160 337 Left join {$wpdb->prefix}wppm_project_users proj_users ON Task.project = proj_users.proj_id
161 - Left join {$wpdb->base_prefix}users user ON (FIND_IN_SET(user.id,Task.users)>0) AND user.display_name LIKE '$search_tag_text'
338 + Left join {$wpdb->base_prefix}users user ON (FIND_IN_SET(user.ID,Task.users)>0)
162 339 Left join {$wpdb->prefix}wppm_project_meta proj_meta ON Task.project = proj_meta.project_id");
163 340 }
164 341 else{
165 342 if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin'){
@@ -190,31 +367,207 @@
190 367 $no_of_rows = ( "SELECT count(*) FROM ($query");
191 368 if(!empty($search_tag )){
192 369 if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin'){
193 370 if(!empty($public_projects)){
194 - $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') $wppm_proj_attr ";
371 + //$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') $wppm_proj_attr ";
372 + $where = $wpdb->prepare( " WHERE (proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) AND $wppm_tl_filter AND $wppm_task_by_proj_filter
373 + AND (
374 + Task.task_name LIKE %s
375 + OR proj.project_name LIKE %s
376 + OR task_statuses.name LIKE %s
377 + OR task_priorities.name LIKE %s
378 + OR user.display_name LIKE %s
379 + ) $wppm_proj_attr",
380 + $search_tag_text,
381 + $search_tag_text,
382 + $search_tag_text,
383 + $search_tag_text,
384 + $search_tag_text
385 + );
195 386 }else{
196 - $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') $wppm_proj_attr ";
387 + $where = $wpdb->prepare(
388 + " WHERE $wppm_tl_filter
389 + AND $wppm_task_by_proj_filter
390 + AND (
391 + Task.task_name LIKE %s
392 + OR proj.project_name LIKE %s
393 + OR task_statuses.name LIKE %s
394 + OR task_priorities.name LIKE %s
395 + OR user.display_name LIKE %s
396 + )
397 + $wppm_proj_attr",
398 + $search_tag_text,
399 + $search_tag_text,
400 + $search_tag_text,
401 + $search_tag_text,
402 + $search_tag_text
403 + );
197 404 }
198 405 } else{
199 406 if(!empty($public_projects)){
200 - $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 (((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 (FIND_IN_SET('$current_user->ID',proj.users)>0))) 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')) $wppm_proj_attr";
201 - }else{
202 - $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 (FIND_IN_SET('$current_user->ID',proj.users)>0))) 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')) $wppm_proj_attr";
407 + $where = $wpdb->prepare(
408 + " WHERE
409 + (proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) AND (proj.is_archived = 0)
410 + AND $wppm_tl_filter
411 + AND $wppm_task_by_proj_filter
412 + AND (
413 + (
414 + FIND_IN_SET(%d, Task.users) > 0
415 + OR Task.created_by = %d
416 + OR (
417 + proj_users.user_id = %d
418 + AND proj_users.role_id = 1
419 + AND FIND_IN_SET(%d, proj.users) > 0
420 + )
421 + OR (
422 + Task.project = proj_meta.project_id
423 + AND proj_meta.meta_key='public_project'
424 + AND proj_meta.meta_value=1
425 + )
426 + OR (
427 + proj.created_by = %d
428 + AND FIND_IN_SET(%d, proj.users) > 0
429 + )
430 + )
431 + AND (
432 + Task.task_name LIKE %s
433 + OR proj.project_name LIKE %s
434 + OR task_statuses.name LIKE %s
435 + OR task_priorities.name LIKE %s
436 + OR user.display_name LIKE %s
437 + )
438 + )
439 + $wppm_proj_attr",
440 + $current_user->ID,
441 + $cu_id,
442 + $cu_id,
443 + $current_user->ID,
444 + $cu_id,
445 + $current_user->ID,
446 + $search_tag_text,
447 + $search_tag_text,
448 + $search_tag_text,
449 + $search_tag_text,
450 + $search_tag_text
451 + );
452 + }else{
453 + $where = $wpdb->prepare(
454 + " WHERE
455 + (proj.is_archived = 0)
456 + AND $wppm_tl_filter
457 + AND $wppm_task_by_proj_filter
458 + AND (
459 + (
460 + FIND_IN_SET(%d, Task.users) > 0
461 + OR Task.created_by = %d
462 + OR (
463 + proj_users.user_id = %d
464 + AND proj_users.role_id = 1
465 + AND FIND_IN_SET(%d, proj.users) > 0
466 + )
467 + OR (
468 + Task.project = proj_meta.project_id
469 + AND proj_meta.meta_key='public_project'
470 + AND proj_meta.meta_value=1
471 + )
472 + OR (
473 + proj.created_by = %d
474 + AND FIND_IN_SET(%d, proj.users) > 0
475 + )
476 + )
477 + AND (
478 + Task.task_name LIKE %s
479 + OR proj.project_name LIKE %s
480 + OR task_statuses.name LIKE %s
481 + OR task_priorities.name LIKE %s
482 + OR user.display_name LIKE %s
483 + )
484 + )
485 + $wppm_proj_attr",
486 + $current_user->ID,
487 + $cu_id,
488 + $cu_id,
489 + $current_user->ID,
490 + $cu_id,
491 + $current_user->ID,
492 + $search_tag_text,
493 + $search_tag_text,
494 + $search_tag_text,
495 + $search_tag_text,
496 + $search_tag_text
497 + );
203 498 }
204 499 }
205 500 }else{
206 501 if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin'){
207 502 if(!empty($public_projects)){
208 - $where = " where (proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) AND $wppm_tl_filter AND $wppm_task_by_proj_filter $wppm_proj_attr";
503 + $where = $wpdb->prepare(
504 + " WHERE
505 + (proj_meta.meta_key = %s AND proj_meta.meta_value = %d)
506 + AND (proj.is_archived = 0)
507 + AND $wppm_tl_filter
508 + AND $wppm_task_by_proj_filter
509 + $wppm_proj_attr",
510 + 'public_project',
511 + 1
512 + );
209 513 }else{
210 - $where = " where $wppm_tl_filter AND $wppm_task_by_proj_filter $wppm_proj_attr";
514 + $where = " where (proj.is_archived = 0) AND $wppm_tl_filter AND $wppm_task_by_proj_filter $wppm_proj_attr";
211 515 }
212 516 } else{
213 517 if(!empty($public_projects)){
214 - $where = " where (proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) AND $wppm_tl_filter AND $wppm_task_by_proj_filter $wppm_proj_attr";
518 + $where = $wpdb->prepare(
519 + " WHERE
520 + (
521 + proj_meta.meta_key = %s
522 + AND proj_meta.meta_value = %d
523 + )
524 + AND (proj.is_archived = 0)
525 + AND $wppm_tl_filter
526 + AND $wppm_task_by_proj_filter
527 + $wppm_proj_attr",
528 + 'public_project',
529 + 1
530 + );
215 531 }else{
216 - $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 (FIND_IN_SET('$current_user->ID',proj.users)>0))) $wppm_proj_attr";
532 + $where = $wpdb->prepare(
533 + " WHERE
534 + (proj.is_archived = 0)
535 + AND $wppm_tl_filter
536 + AND $wppm_task_by_proj_filter
537 + AND (
538 + (
539 + FIND_IN_SET(%d, Task.users) > 0
540 + )
541 + OR (
542 + Task.created_by = %d
543 + )
544 + OR (
545 + proj_users.user_id = %d
546 + AND proj_users.role_id = %d
547 + AND FIND_IN_SET(%d, proj.users) > 0
548 + )
549 + OR (
550 + Task.project = proj_meta.project_id
551 + AND proj_meta.meta_key = %s
552 + AND proj_meta.meta_value = %d
553 + )
554 + OR (
555 + proj.created_by = %d
556 + AND FIND_IN_SET(%d, proj.users) > 0
557 + )
558 + )
559 + $wppm_proj_attr",
560 + $current_user->ID,
561 + $cu_id,
562 + $cu_id,
563 + 1,
564 + $current_user->ID,
565 + 'public_project',
566 + 1,
567 + $cu_id,
568 + $current_user->ID
569 + );
217 570 }
218 571 }
219 572 }
220 573 $query = apply_filters('wppm_task_list_list_view_query',$query,$search_tag_text);
@@ -226,10 +579,8 @@
226 579 $no_of_rows_where = $where." Group by Task.id) AS Task";
227 580 $no_of_rows .= $no_of_rows_where;
228 581 $no_of_rows = apply_filters('wppm_task_list_no_of_rows',$no_of_rows,$wppm_tl_filter,$search_tag_text);
229 582 $totalrows = $wpdb->get_var($no_of_rows);
230 -$sort_by = esc_sql($sort_by);
231 -$order = esc_sql($order);
232 583 $query .= $where." Group by Task.id ORDER BY ".$sort_by." ".$order."";
233 584 $query = apply_filters('wppm_task_list_query',$query);
234 585 $limit_start=$page_no*$task_per_page;
235 586 $limit="\n LIMIT ".$limit_start.",".$task_per_page." ";
@@ -236,9 +587,9 @@
236 587 $task_id_array = array();
237 588 $query = $query.$limit;
238 589 $wppm_task_fillter = $wpdb->get_results($query);
239 590 $flag = false;
240 -$project_creator = $wpdb->get_var("SELECT created_by FROM {$wpdb->prefix}wppm_project WHERE created_by = '$cu_id'");
591 +$project_creator = $wpdb->get_var($wpdb->prepare("SELECT created_by FROM {$wpdb->prefix}wppm_project WHERE created_by = %d",$cu_id));
241 592 if(!empty($wppm_task_fillter)){
242 593 foreach($wppm_task_fillter as $key_filter=>$val_filter){
243 594 $val_array = (array) $val_filter;
244 595 $tusers = $val_array['users'];
@@ -244,10 +595,10 @@
244 595 $tusers = $val_array['users'];
245 596 $tusers_arr = explode(',',$tusers);
246 597 $tproject_id = esc_sql($val_array['project']);
247 598 if(!empty($tusers) && in_array($current_user->ID,$tusers_arr)){
248 - $project_user_role = $wpdb->get_var("SELECT role_id FROM {$wpdb->prefix}wppm_project_users WHERE proj_id = '$tproject_id' AND user_id = '$cu_id'");
249 - $project_users = $wpdb->get_var("SELECT users FROM {$wpdb->prefix}wppm_project WHERE id = '$tproject_id'");
599 + $project_user_role = $wpdb->get_var($wpdb->prepare("SELECT role_id FROM {$wpdb->prefix}wppm_project_users WHERE proj_id = %d AND user_id = %d",$tproject_id,$cu_id));
600 + $project_users = $wpdb->get_var($wpdb->prepare("SELECT users FROM {$wpdb->prefix}wppm_project WHERE id = %d",$tproject_id));
250 601 $project_users_arr = explode(',',(string)$project_users);
251 602 if(((!empty($project_user_role)) && ($project_user_role == 1) && in_array($current_user->ID,$project_users_arr))){
252 603 $flag= true;
253 604 break;
@@ -290,12 +641,19 @@
290 641 <div class="row">
291 642 <div class="col-sm-12" id="wppm_heading_inline">
292 643 <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>
293 644 <span class="wppm-add-new-btn btn-primary" id="wppm_add_new_task_btn_tl" style="background-color:<?php echo esc_attr($appearance_settings['list-header-button-background-color'])?>;color:<?php echo esc_attr($appearance_settings['list-header-button-text-color'])?>;<?php echo esc_attr($style)?>;" onclick="wppm_add_new_task()"><img class="wppm_add_new_task_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/plus_icon.svg'); ?>" alt="add_icon"><?php echo esc_html_e('Add New','taskbuilder');?></span>
645 + <!-- Dashboard Button -->
646 + <a class="wppm-add-new-btn btn-primary" style="background-color:<?php echo esc_attr($appearance_settings['list-header-button-background-color'])?>;color:<?php echo esc_attr($appearance_settings['list-header-button-text-color'])?>;<?php echo esc_attr($style)?>;" href="<?php echo esc_url( admin_url('admin.php?page=wppm-dashboard') ); ?>"
647 + style="margin-right:10px;" title="<?php echo esc_attr_e('Go to Dashboard','taskbuilder'); ?>">
648 + <img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/dashboard.svg'); ?>" alt="dashboard_icon">
649 + <?php esc_html_e('Dashboard','taskbuilder'); ?>
650 + </a>
651 + </span>
294 652 </div>
295 653 </div>
296 - <div style="display:flex;justify-content:space-between;margin-top:20px;flex-wrap: wrap;">
297 - <div style="display:flex;flex-wrap: wrap;min-width: 0; max-width: 100%; ">
654 + <div>
655 + <div style="display:flex;flex-wrap: wrap;min-width: 0; max-width: 100%;margin-top: 20px;">
298 656 <div id="wppm_task_filter_container">
299 657 <div class="wppm-bulk-actions"style="margin-left: -14px !important;">
300 658 <button
301 659 id="wppm-task-bulk-actions-btn"
@@ -319,12 +677,12 @@
319 677 <div class="wppm-filter-item">
320 678 <label for="wppm_task_filter" style="margin-left:20px;"> <?php echo esc_html_e('Filter','taskbuilder');?></label>
321 679 <select id="wppm_task_filter" name="wppm_task_filter" onchange="wppm_apply_task_filter('<?php echo esc_attr($page); ?>')" style="margin-left:20px;">
322 680 <option value="all"<?php echo ($filter_by == "all")? 'selected':""?>><?php echo esc_html_e('All','taskbuilder');?></option>
323 - <option value="1" style="<?php echo esc_attr($todo_status_style); ?>" <?php echo ($filter_by == "1")? 'selected':""?>><?php echo esc_html_e($todo_status_name,'taskbuilder');?></option>
324 - <option value="2" style="<?php echo esc_attr($inp_status_style); ?>" <?php echo ($filter_by == "2")? 'selected':""?>><?php echo esc_html_e($inp_status_name,'taskbuilder');?></option>
325 - <option value="3" style="<?php echo esc_attr($hold_status_style); ?>" <?php echo ($filter_by == "3")? 'selected':""?>><?php echo esc_html_e($hold_status_name,'taskbuilder');?></option>
326 - <option value="4" style="<?php echo esc_attr($completed_status_style); ?>" <?php echo ($filter_by == "4")? 'selected':""?>><?php echo esc_html_e($completed_status_name,'taskbuilder');?></option>
681 + <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>
682 + <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>
683 + <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>
684 + <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>
327 685 <option value="mine" <?php echo ($filter_by == "mine")? 'selected':""?>><?php echo esc_html_e('Mine','taskbuilder');?></option>
328 686 <option value="unassigned" <?php echo ($filter_by == "unassigned")? 'selected':""?>><?php echo esc_html_e('Unassigned','taskbuilder');?></option>
329 687 <option value="overdue" <?php echo ($filter_by == "overdue")? 'selected':""?>><?php echo esc_html_e('Overdue','taskbuilder');?></option>
330 688 <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>
@@ -331,22 +689,89 @@
331 689 </select>
332 690 </div>
333 691 </div>
334 692 </div>
335 - <div class="wppm-filter-item wppm_project_autocomplete_container" style="margin: 0 0 0 28px;">
336 - <label for="wppm_task_list_proj_filter">
337 - <?php echo esc_html_e('Project','taskbuilder');?>
338 - </label><br>
339 - <select searchable="search here" onchange="wppm_tasks_by_select_project('<?php echo esc_attr($page); ?>')" class="form-control" size="40" name="wppm_task_list_proj_filter" id="wppm_task_list_proj_filter" data-width="100%" style="width: 100%!important;">
340 - <option value="0" <?php echo ($proj_filter == 0)? 'selected':""?>><?php echo esc_html_e('All','taskbuilder');?></option>
693 + <div class="wppm-filter-item wppm_project_autocomplete_container" style="margin: 0 0 0 20px;">
694 + <label for="wppm_task_list_proj_filter">
695 + <?php echo esc_html_e('Project','taskbuilder');?>
696 + </label><br>
697 + <select searchable="search here" onchange="wppm_tasks_by_select_project('<?php echo esc_attr($page); ?>')" class="form-control" size="40" name="wppm_task_list_proj_filter" id="wppm_task_list_proj_filter" data-width="100%" style="width: 100%!important;">
698 + <option value="0" <?php echo ($proj_filter == 0)? 'selected':""?>><?php echo esc_html_e('All','taskbuilder');?></option>
699 + <?php
700 + if(!empty($projects)){
701 + foreach($projects as $proj) {
702 + ?><option value="<?php echo esc_attr($proj->id)?>" <?php echo ($proj_filter == $proj->id)? 'selected':""?>><?php echo esc_html($proj->project_name,'taskbuilder');?></option>
703 + <?php }
704 + } ?>
705 + </select>
706 + </div>
707 + <!-- FILTER BUTTON -->
708 + <div class="tb-filters" class="wppm-filter-item" style="display:flex;margin-left: 4px;">
709 + <div class="tb-filter-bar">
710 + <span id="tb-advanced-toggle" class="tb-btn" style="margin-top:0px!important;">
711 + <?php echo esc_html_e('⚙️ Filters', 'taskbuilder'); ?>
712 + </span>
713 +
714 + <!-- ACTIVE FILTER CHIPS -->
715 + <div id="tb-active-filters" class="tb-chips"></div>
716 +
717 + <!-- POPOVER -->
718 + <div id="tb-advanced-panel" class="tb-popover">
719 + <div class="tb-mobile-header">
720 + <span><?php echo esc_html_e('Filters', 'taskbuilder'); ?></span>
721 + <button type="button" id="tb-close-filters">✕</button>
722 + </div>
723 + <div class="tb-arrow"></div>
724 +
725 + <div class="tb-section">
726 + <h4> <?php echo esc_html_e('Created By', 'taskbuilder'); ?></h4>
727 + <select id="tb-created-by" class="form-control" multiple>
341 728 <?php
342 - if(!empty($projects)){
343 - foreach($projects as $proj) {
344 - ?>
345 - <option value="<?php echo esc_attr($proj->id)?>" <?php echo ($proj_filter == $proj->id)? 'selected':""?>><?php echo esc_html_e($proj->project_name,'taskbuilder');?></option>
346 - <?php }
347 - } ?>
729 + if(!empty($users)){
730 + foreach($users as $user): ?>
731 + <option value="<?php echo esc_attr($user->ID); ?>"><?php echo esc_html($user->display_name); ?></option>
732 + <?php endforeach; ?>
733 + <?php } ?>
734 + </select>
735 + <h4> <?php echo esc_html_e('Assigned To', 'taskbuilder'); ?></h4>
736 + <select id="tb-assigned" multiple>
737 + <?php
738 + if(!empty($all_assigned)){
739 + foreach($all_assigned as $uid){
740 + $user = get_userdata($uid);
741 + if($user){ ?>
742 + <option value="<?php echo esc_attr($uid); ?>">
743 + <?php echo esc_html($user->display_name); ?>
744 + </option>
745 + <?php }
746 + }
747 + }
748 + ?>
348 749 </select>
750 + </div>
751 + <div class="tb-section">
752 + <h4> <?php echo esc_html_e('Priority', 'taskbuilder'); ?></h4>
753 + <select id="tb-priority" class="form-control" multiple>
754 + <?php if(!empty($priorities)) {
755 + foreach($priorities as $priority){ ?>
756 + <option value="<?php echo esc_attr($priority->id); ?>">
757 + <?php echo esc_html($priority->name); ?>
758 + </option>
759 + <?php } } ?>
760 + </select>
761 + </div>
762 + <div class="tb-section">
763 + <h4> <?php echo esc_html_e('Date', 'taskbuilder'); ?></h4>
764 + <input type="date" class="form-control" id="tb-start-date">
765 + <input type="date" class="form-control"id="tb-end-date">
766 + </div>
767 + <div id="tb-filter-actions">
768 + <button class="wppm-submit-btn" id="tb-apply-filter" type="button"> <?php echo esc_html_e('Apply', 'taskbuilder'); ?></button>
769 + <button class="wppm_reset_btn" id="tb-reset-filter" type="button"> <?php echo esc_html_e('Reset', 'taskbuilder'); ?></button>
770 + </div>
771 + </div>
772 + </div>
773 + <div id="tb-backdrop"></div>
349 774 </div>
350 775 <div class="wppm_display_submit" style="margin: 0 0 -5px 10px;">
351 776 <div class="wppm-filter-actions">
352 777 <span class="wppm-link" onclick="wppm_tl_reset_filter('<?php echo esc_attr($page); ?>')"> <?php echo esc_html_e('Reset','taskbuilder');?></span>
@@ -351,19 +776,19 @@
351 776 <div class="wppm-filter-actions">
352 777 <span class="wppm-link" onclick="wppm_tl_reset_filter('<?php echo esc_attr($page); ?>')"> <?php echo esc_html_e('Reset','taskbuilder');?></span>
353 778 </div>
354 779 </div>
355 - </div>
356 - <div id="wppm_task_search" style="display:flex;justify-content:flex-end;">
357 - <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">
358 - <input type="search" id="wppm_task_search_filter" style="margin-right:10px;" name="wppm_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) : "" ?>">
780 + <div id="wppm_task_search" style="display:flex;justify-content:flex-end;margin-left: auto;">
781 + <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">
782 + <input type="search" id="wppm_task_search_filter" style="margin-right:10px;" name="wppm_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) : "" ?>">
359 783 </div>
360 784 </div>
361 785 </div>
362 - <div style="display:flex;justify-content:flex-end;margin-right: 10px;">
363 - <span id="wppm_grid_view_btn" onclick="wppm_view_task_search_filter(<?php echo esc_attr($page_no)?>,'<?php echo esc_attr($page)?>')"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/grid_view.svg'); ?>" alt="grid_view"><span><?php echo esc_html_e('Grid view','taskbuilder');?></span></span>
364 - </div>
365 786 </div>
787 + <div style="display:flex;justify-content:flex-end;margin-right: 10px;">
788 + <span id="wppm_grid_view_btn" onclick="wppm_view_task_search_filter('<?php echo esc_attr($page_no)?>','<?php echo esc_attr($page)?>','<?php echo esc_attr($project_id)?>')"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/grid_view.svg'); ?>" alt="grid_view"><span><?php echo esc_html_e('Grid view','taskbuilder');?></span></span>
789 + </div>
790 + </div>
366 791 <script>
367 792 jQuery('#wppm-more-actions-btn, #wppm-task-bulk-actions-btn').gpopover({width: 200});
368 793 </script>
369 794 <div id="wppm_task_table_container" class="wppm_task_table_container table-responsive" style="padding: 0 15px 15px 15px;">
@@ -397,9 +822,9 @@
397 822 <span id="wppm_priority_th" style="color:<?php echo esc_attr($appearance_settings['list-header-text-color'])?>"><?php echo esc_html_e('Priority','taskbuilder'); ?></span>
398 823 <img width="16" height="16" style = "<?php echo ($sort_by == ('task_priorities.name') && $order == 'DESC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('priority','ASC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_up_priority_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
399 824 <img width="16" height="16" style = "<?php echo ($sort_by == ('task_priorities.name') && $order == 'ASC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('priority','DESC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_down_priority_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_down_icon.svg'); ?>" alt="chevron_sort_down_icon">
400 825 </th>
401 - <?php if($wppm_default_task_date == 1) { ?>
826 + <?php if($wppm_default_task_date == 1 && $wppm_deafault_time_duration_task==0) { ?>
402 827 <th class="wppm_table_header" style="background-color:<?php echo esc_attr($appearance_settings['list-header-background-color'])?>">
403 828 <span id="wppm_start_date_th" style="color:<?php echo esc_attr($appearance_settings['list-header-text-color'])?>"><?php echo esc_html_e('Start date','taskbuilder'); ?></span>
404 829 <img width="16" height="16" style = "<?php echo ($sort_by == 'Task.start_date' && $order == 'DESC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('start_date','ASC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_up_start_date_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
405 830 <img width="16" height="16" style = "<?php echo ($sort_by == 'Task.start_date' && $order == 'ASC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('start_date','DESC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_down_start_date_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_down_icon.svg'); ?>" alt="chevron_sort_down_icon">
@@ -408,9 +833,16 @@
408 833 <span id="wppm_end_date_th" style="color:<?php echo esc_attr($appearance_settings['list-header-text-color'])?>"><?php echo esc_html_e('End date','taskbuilder'); ?></span>
409 834 <img width="16" height="16" style = "<?php echo ($sort_by == 'Task.end_date' && $order == 'DESC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('end_date','ASC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_up_end_date_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
410 835 <img width="16" height="16" style = "<?php echo ($sort_by == 'Task.end_date' && $order == 'ASC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('end_date','DESC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_down_end_date_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_down_icon.svg'); ?>" alt="chevron_sort_down_icon">
411 836 </th>
412 - <?php } ?>
837 + <?php }
838 + if( $wppm_deafault_time_duration_task==1){ ?>
839 + <th class="wppm_table_header" style="background-color:<?php echo esc_attr($appearance_settings['list-header-background-color'])?>">
840 + <span id="wppm_task_duration_th" style="color:<?php echo esc_attr($appearance_settings['list-header-text-color'])?>"><?php echo esc_html_e('Duration','taskbuilder'); ?></span>
841 + <img width="16" height="16" style = "<?php echo ($sort_by == 'TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)' && $order == 'DESC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)','ASC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_up_task_duration_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
842 + <img width="16" height="16" style = "<?php echo ($sort_by == 'TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)' && $order == 'ASC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)','DESC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_down_task_duration_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_down_icon.svg'); ?>" alt="chevron_sort_down_icon">
843 + </th>
844 + <?php }?>
413 845 <th class="wppm_table_header" style="background-color:<?php echo esc_attr($appearance_settings['list-header-background-color'])?>">
414 846 <span style="color:<?php echo esc_attr($appearance_settings['list-header-text-color'])?>"><?php echo esc_html_e('Assign To','taskbuilder'); ?></span>
415 847 </th>
416 848 <th class="wppm_table_header" style="background-color:<?php echo esc_attr($appearance_settings['list-header-background-color'])?>">
@@ -421,36 +853,60 @@
421 853 </thead>
422 854 <tbody>
423 855 <?php
424 856 $task_index = 0;
857 + $statuses = $wpdb->get_results(
858 + "SELECT * FROM {$wpdb->prefix}wppm_task_statuses",
859 + OBJECT_K
860 + );
861 +
862 + $priorities = $wpdb->get_results(
863 + "SELECT * FROM {$wpdb->prefix}wppm_task_priorities",
864 + OBJECT_K
865 + );
866 + $projects = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_project", OBJECT_K) ;
867 + $task_ids = wp_list_pluck($wppm_task_fillter, 'id');
868 + $checklist_counts = [];
869 + if (!empty($task_ids)) {
870 + $task_ids_sql = implode(',', array_map('absint', $task_ids));
871 + $checklist_results = $wpdb->get_results(" SELECT checklist.task_id,
872 + COUNT(Items.id) AS total_items,
873 + SUM(CASE WHEN Items.checked = 1 THEN 1 ELSE 0 END) AS checked_items
874 + FROM {$wpdb->prefix}wppm_checklist_items AS Items
875 + LEFT JOIN {$wpdb->prefix}wppm_checklist AS checklist
876 + ON Items.checklist_id = checklist.id
877 + WHERE checklist.task_id IN ($task_ids_sql)
878 + GROUP BY checklist.task_id"
879 + );
880 + foreach ($checklist_results as $row) {
881 + $checklist_counts[$row->task_id] = [
882 + 'total' => (int) $row->total_items,
883 + 'checked' => (int) $row->checked_items,
884 + ];
885 + }
886 + }
425 887 if(!empty($wppm_task_fillter)){
426 888 foreach($wppm_task_fillter as $task) {
427 - $task_id = esc_sql($task->id);
428 - $checklists = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_checklist where task_id = '$task_id'" );
889 + $task_id = absint($task->id);
890 + $wppm_task_duration = $wppmfunction->wppm_get_duration($task->start_date,$task->end_date);
891 + $checklists = $wpdb->get_results( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_checklist where task_id = %d",$task_id) );
429 892 if(!empty($task)){
430 893 $taskdata = $wppmfunction->get_task($task->id);
431 894 $project_data = $wppmfunction->get_project($task->project);
432 895 $task_index++;
433 - $total=$wpdb->get_var("SELECT COUNT(Items.id) AS check_id
434 - FROM {$wpdb->prefix}wppm_checklist_items AS Items
435 - Left join {$wpdb->prefix}wppm_checklist checklist ON Items.checklist_id = checklist.id
436 - WHERE checklist.task_id = '$task_id'");
437 - $total_checked_items=$wpdb->get_var("SELECT COUNT(Items.id) AS check_id
438 - FROM {$wpdb->prefix}wppm_checklist_items AS Items
439 - Left join {$wpdb->prefix}wppm_checklist checklist ON Items.checklist_id = checklist.id
440 - WHERE checklist.task_id = '$task_id' AND Items.checked=1");
441 -
896 + $total = $checklist_counts[$task_id]['total'] ?? 0;
897 + $total_checked_items = $checklist_counts[$task_id]['checked'] ?? 0;
442 898 if(isset($task->status)){
443 - $tstatus = esc_sql($task->status);
444 - $status = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}wppm_task_statuses where id = '$tstatus'" );
899 + $tstatus = absint($task->status);
900 + $status = $statuses[$task->status] ?? null;
445 901 }
446 902 if(!empty($task->priority)){
447 - $tpriority = esc_sql($task->priority);
448 - $priority = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}wppm_task_priorities where id ='$tpriority' " );
903 + $tpriority = absint($task->priority);
904 + $priority = $priorities[$task->priority] ?? null;
449 905 }
450 906 if(isset($task->project)){
451 - $tproj = esc_sql($task->project);
452 - $project = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}wppm_project where id = '$tproj'" );
907 + $tproj = absint($task->project);
908 + $project = $projects[$task->project] ?? null;
453 909 }
454 910 if($wppm_task_time == 1){
455 911 $tsDate = new DateTime($task->start_date);
456 912 $teDate = new DateTime($task->end_date);
@@ -485,9 +941,8 @@
485 941 $task_end_date = $teDate->format($wppm_date_setting);
486 942 }else{
487 943 $task_end_date = isset($task->end_date) ? $task->end_date: "" ;
488 944 }
489 -
490 945 }
491 946 } elseif($wppm_task_time == 0){
492 947 $tsDate = new DateTime($task->start_date);
493 948 $teDate = new DateTime($task->end_date);
@@ -539,9 +994,9 @@
539 994 }
540 995 }
541 996 $url = $wppmfunction->get_task_url( $task->id, $is_frontend );
542 997 ?>
543 - <tr onclick= "if(link)wppm_tl_handle_click(event, <?php echo esc_attr($task->id) ?>, '<?php echo esc_url( $url ); ?>')" >
998 + <tr onclick= "if(link)wppm_tl_handle_click(event, <?php echo esc_attr($task->id) ?>, '<?php echo esc_url( $url ); ?>',<?php echo esc_attr($project_id) ?>)" >
544 999 <td class="bulk-selector" onmouseover="link=false;" onmouseout="link=true;">
545 1000 <div class="wppm-pl-item-selector">
546 1001 <div class="checkbox-container">
547 1002 <input id="wppm_bulk_select_<?php echo esc_attr($task->id) ?>" class="wppm-task-bulk-select" type="checkbox" onchange="wppm_bulk_task_item_select_change();" value="<?php echo esc_attr( $task->id ); ?>"/>
@@ -549,41 +1004,54 @@
549 1004 </div>
550 1005 </div>
551 1006 </td>
552 1007 <td onmouseover="link=true;">
553 - <?php echo esc_html_e($task->task_name,'taskbuilder') ?>
1008 + <?php echo esc_html($task->task_name) ?>
1009 + <?php $wppm_row_subtask_progress = $wppmfunction->get_subtask_progress($task->id);
1010 + if($wppm_row_subtask_progress['total'] > 0){ ?>
1011 + <span class="wppm_subtask_badge" title="<?php esc_attr_e('Subtasks','taskbuilder'); ?>"><?php echo esc_html($wppm_row_subtask_progress['completed'].'/'.$wppm_row_subtask_progress['total']); ?></span>
1012 + <?php } ?>
554 1013 </td>
555 1014 <td onmouseover="link=true;">
556 1015 <?php if(!empty($project->project_name)){
557 - echo esc_html_e($project->project_name,'taskbuilder');
1016 + echo esc_html($project->project_name);
558 1017 }
559 1018 ?>
560 1019 </td>
561 1020 <td onmouseover="link=true;">
562 1021 <?php if(!empty($task->status)){ ?>
563 - <span class="wppm_td_task_status" style="background-color:<?php echo (isset($status->bg_color))? esc_attr($status->bg_color):"";?>; color: <?php echo (isset($status->color))? esc_attr($status->color):""; ?>"><?php echo (isset($status->name))? esc_html_e($status->name,'taskbuilder'):"" ?></span>
1022 + <span class="wppm_td_task_status" style="background-color:<?php echo (isset($status->bg_color))? esc_attr($status->bg_color):"";?>; color: <?php echo (isset($status->color))? esc_attr($status->color):""; ?>"><?php echo (isset($status->name))? esc_html($status->name):"" ?></span>
564 1023 <?php } ?>
565 1024 </td>
566 1025 <td onmouseover="link=true;">
567 1026 <?php if(!empty($task->priority)){ ?>
568 - <span class ="wppm_td_task_priority" style="background-color:<?php echo (isset($priority->bg_color))? esc_attr($priority->bg_color):"" ;?>; color: <?php echo (isset($priority->color))? esc_attr($priority->color):""; ?>"><?php echo (isset($priority->name))? esc_html_e($priority->name,'taskbuilder'):"" ?></span>
1027 + <span class ="wppm_td_task_priority" style="background-color:<?php echo (isset($priority->bg_color))? esc_attr($priority->bg_color):"" ;?>; color: <?php echo (isset($priority->color))? esc_attr($priority->color):""; ?>"><?php echo (isset($priority->name))? esc_html($priority->name):"" ?></span>
569 1028 <?php } ?>
570 1029 </td>
571 - <?php if($wppm_default_task_date == 1) { ?>
1030 + <?php if($wppm_default_task_date == 1 && $wppm_deafault_time_duration_task==0) { ?>
572 1031 <td onmouseover="link=true;">
573 1032 <?php if(!empty($task_start_date)){ ?>
574 - <?php echo esc_html_e($task_start_date,'taskbuilder');
1033 + <?php echo esc_html($task_start_date);
575 1034 } ?>
576 1035 </td>
577 - <td onmouseover="link=true;">
578 - <?php if(!empty($task_end_date) && ($task->status!=4 && $task_end_date < $current_date && $task_end_date != '0000-00-00 00:00:00' && $task_end_date != '00-00-0000 00:00:00' && $task_end_date != '00-00-0000' && $task_end_date != '0000-00-00')){
1036 + <td onmouseover="link=true;"><?php
1037 + if(!empty($task_end_date) && ($task->status!=4 && $task_end_date < $current_date && $task_end_date != '0000-00-00 00:00:00' && $task_end_date != '00-00-0000 00:00:00' && $task_end_date != '00-00-0000' && $task_end_date != '0000-00-00')){
579 1038 $style = "color:#FF0000";
580 1039 } else{
581 1040 $style = "color:#2C3E50";
582 1041 }?>
583 - <span style="<?php echo esc_attr($style); ?>"><?php echo esc_html_e($task_end_date,'taskbuilder');?></span>
1042 + <span style="<?php echo esc_attr($style); ?>"><?php echo esc_html($task_end_date);?></span>
584 1043 </td>
585 1044 <?php } ?>
1045 + <?php if($wppm_deafault_time_duration_task==1){ ?>
1046 + <?php
1047 + if(!empty($task_end_date) && ($task->status!=4 && $task_end_date < $current_date && $task_end_date != '0000-00-00 00:00:00' && $task_end_date != '00-00-0000 00:00:00' && $task_end_date != '00-00-0000' && $task_end_date != '0000-00-00')){
1048 + $style = "color:#FF2222";
1049 + } else {
1050 + $style = "color:#2C3E50";
1051 + } ?>
1052 + <td onmouseover="link=true;" class="wppm_table_td"><span style="<?php echo esc_attr($style); ?>"><?php echo isset($wppm_task_duration) ? esc_html($wppm_task_duration):"" ?></span></td>
1053 + <?php } ?>
586 1054 </td>
587 1055 <td onmouseover="link=true;" style="text-align:center;">
588 1056 <?php
589 1057 $i=0;
@@ -635,13 +1103,13 @@
635 1103 ?>
636 1104 </tbody>
637 1105 </table>
638 1106 <script>
639 - function wppm_tl_handle_click(event, id, url) {
1107 + function wppm_tl_handle_click(event, id, url,project_id) {
640 1108 if ( ( event.ctrlKey || event.metaKey ) && url ) {
641 1109 window.open(url, '_blank');
642 1110 } else {
643 - wppm_open_task(id);
1111 + wppm_open_task(id,project_id);
644 1112 }
645 1113 }
646 1114 </script>
647 1115 <?php
@@ -653,9 +1121,9 @@
653 1121 $next_class=($total_pages==$current_page)?'disabled':'';
654 1122 ?>
655 1123 <div class="row" style="background-color:#ffffff;">
656 1124 <div class="col-sm-12">
657 - <div class="wppm_task_result" style="<?php echo esc_attr($total_pages==0)? '':'display: none;';?>"><?php _e('Your search request returned no results.','taskbuilder');?></div>
1125 + <div class="wppm_task_result" style="<?php echo esc_attr($total_pages==0)? '':'display: none;';?>"><?php esc_html_e('Your search request returned no results.','taskbuilder');?></div>
658 1126 <hr style="<?php echo esc_attr($total_pages==0)? '':'display: none;';?>">
659 1127 </div>
660 1128 <div>
661 1129 </div>
@@ -705,8 +1173,14 @@
705 1173 .select2-container {
706 1174 max-width: 150px !important;
707 1175 min-width: 150px !important;
708 1176 }
1177 +
1178 + .select2-selection--multiple {
1179 + max-width: 290px !important;
1180 + min-width: 290px !important;
1181 + }
1182 +
709 1183 #wppm_task_filter{
710 1184 min-height: 30px !important;
711 1185 max-height: 35px !important;
712 1186 }
@@ -728,16 +1202,90 @@
728 1202 background-color:<?php echo esc_attr($appearance_settings['list-header-button-hover-color'])?>!important;
729 1203 }
730 1204 </style>
731 1205 <script type="text/javascript">
732 - var link = true;
733 - jQuery( document ).ready( function( jQuery ) {
734 - jQuery("input[name='wppm_task_search_filter']").keypress(function(e) {
735 - //Enter key
736 - if (e.which == 13) {
737 - wppm_task_search_filter('<?php echo esc_attr($page); ?>');
738 - }
739 - });
1206 + var link = true;
1207 + window.listFilters = window.listFilters || {
1208 + created_by: [],
1209 + assigned: [],
1210 + priority: [],
1211 + start_date: "",
1212 + end_date: ""
1213 + };
1214 +
1215 + var listFilters = window.listFilters;
1216 + jQuery( document ).ready( function( jQuery ) {
1217 + // SET VALUES AFTER INIT
1218 + let createdBy = <?php echo wp_json_encode(array_map('strval', $advanced_filter['created_by'] ?? [])); ?>;
1219 +
1220 + let assigned = <?php echo wp_json_encode(array_map('strval', $advanced_filter['assigned'] ?? [])); ?>;
1221 +
1222 + let priority = <?php echo wp_json_encode(array_map('strval', $advanced_filter['priority'] ?? [])); ?>;
1223 + jQuery('#tb-created-by').val(createdBy).trigger('change');
1224 + jQuery('#tb-assigned').val(assigned).trigger('change');
1225 + jQuery('#tb-priority').val(priority).trigger('change');
1226 + jQuery('#tb-start-date').val('<?php echo esc_attr($advanced_filter['start_date'] ?? ''); ?>');
1227 + jQuery('#tb-end-date').val('<?php echo esc_attr($advanced_filter['end_date'] ?? ''); ?>');
1228 + jQuery(document).off("click", "#tb-apply-filter").on("click", "#tb-apply-filter", function (e) {
1229 + e.preventDefault();
1230 + listFilters.created_by = jQuery("#tb-created-by").val() || [];
1231 + listFilters.assigned = jQuery("#tb-assigned").val() || [];
1232 + listFilters.priority = jQuery("#tb-priority").val() || [];
1233 + listFilters.start_date = jQuery("#tb-start-date").val() || "";
1234 + listFilters.end_date = jQuery("#tb-end-date").val() || "";
1235 + listFilters.id = "<?php echo esc_attr($project_id); ?>";
1236 + renderActiveFilters(listFilters);
1237 + setListFilterCookie(listFilters);
1238 + triggerFilter(1, listFilters,'list');
1239 + });
1240 + jQuery(document).on("click", ".tb-remove", function () {
1241 + let key = jQuery(this).attr("data-key");
1242 + let value = jQuery(this).attr("data-value");
1243 + // DATE REMOVE
1244 + if (key === "date") {
1245 + listFilters.start_date = "";
1246 + listFilters.end_date = "";
1247 + jQuery("#tb-start-date").val("");
1248 + jQuery("#tb-end-date").val("");
1249 + } else {
1250 + listFilters[key] = (listFilters[key] || [])
1251 + .map(String)
1252 + .filter(v => v !== String(value));
1253 + jQuery(`#tb-${key}`).val(listFilters[key]).trigger("change");
1254 + }
1255 + // REMOVE CHIP UI
1256 + jQuery(this).closest(".tb-chip").remove();
1257 + syncUIWithFilters(listFilters);
1258 + // save cookie
1259 + setListFilterCookie(listFilters);
1260 + // reload data
1261 + triggerFilter(1,listFilters,'list');
1262 + });
1263 + jQuery(document)
1264 + .off("click", "#tb-reset-filter").on("click", "#tb-reset-filter", function () {
1265 + resetFilters('list');
1266 + });
1267 + let saved = getListFilterCookie();
1268 + if (saved && typeof saved === "object") {
1269 + window.listFilters = {
1270 + created_by: saved.created_by || [],
1271 + assigned: saved.assigned || [],
1272 + priority: saved.priority || [],
1273 + start_date: saved.start_date || "",
1274 + end_date: saved.end_date || ""
1275 + };
1276 + listFilters = window.listFilters;
1277 + }
1278 + setTimeout(function () {
1279 + syncUIWithFilters(listFilters);
1280 + renderActiveFilters(listFilters);
1281 + }, 100);
1282 + jQuery("input[name='wppm_task_search_filter']").keypress(function(e) {
1283 + //Enter key
1284 + if (e.which == 13) {
1285 + wppm_task_search_filter('<?php echo esc_attr($page); ?>');
1286 + }
1287 + });
740 1288 jQuery("#wppm_task_name_th").hover(function(){
741 1289 jQuery('#wppm_chevron_sort_up_task_name_img').show();
742 1290 jQuery('#wppm_chevron_sort_down_task_name_img').hide();
743 1291 });
@@ -760,12 +1308,22 @@
760 1308 jQuery("#wppm_end_date_th").hover(function(){
761 1309 jQuery('#wppm_chevron_sort_up_end_date_img').show();
762 1310 jQuery('#wppm_chevron_sort_down_end_date_img').hide();
763 1311 });
1312 + jQuery("#wppm_task_duration_th").hover(function(){
1313 + jQuery('#wppm_chevron_sort_up_task_duration_img').show();
1314 + jQuery('#wppm_chevron_sort_down_task_duration_img').hide();
1315 + });
764 1316
765 1317 })
766 1318 jQuery('#wppm_task_list_proj_filter').select2({ dropdownAutoWidth: true, width: 'auto' });
767 1319 jQuery('#wppm_task_list_proj_filter').val(<?php echo esc_attr($proj_filter) ?>);
1320 + jQuery('#tb-created-by').select2({ dropdownAutoWidth: true, width: '100%'});
1321 + jQuery('#tb-created-by').val(<?php echo wp_json_encode($advanced_filter['created_by'] ?? []); ?>).trigger('change');
1322 + jQuery('#tb-assigned').select2({ dropdownAutoWidth: true, width: '100%' });
1323 + jQuery('#tb-assigned').val(<?php echo wp_json_encode($advanced_filter['assigned'] ?? []); ?>).trigger('change');
1324 + jQuery('#tb-priority').select2({dropdownAutoWidth: true, width: '100%'});
1325 + jQuery('#tb-priority').val(<?php echo wp_json_encode($advanced_filter['priority'] ?? []); ?>).trigger('change');
768 1326 /**
769 1327 * Bulk item selector change
770 1328 */
771 1329 function wppm_bulk_task_item_select_change() {
@@ -778,5 +1336,27 @@
778 1336 jQuery("#wppm-task-bulk-actions-btn").hide();
779 1337 jQuery(".wppm-bulk-selector").prop("checked", false);
780 1338 }
781 1339 }
782 -</script>
1340 + jQuery(document).off("click", "#tb-advanced-toggle").on("click", "#tb-advanced-toggle", function (e) {
1341 + e.stopPropagation();
1342 + jQuery("#tb-advanced-panel").toggleClass("tb-open");
1343 + });
1344 +
1345 + /* Close on backdrop click */
1346 + jQuery(document).on("click", "#tb-backdrop", function () {
1347 + jQuery("#tb-advanced-panel").removeClass("tb-open");
1348 + jQuery(this).removeClass("active");
1349 + });
1350 +
1351 + /* Close on outside (desktop only) */
1352 + jQuery(document).on("click", function (e) {
1353 + if (window.innerWidth > 768) {
1354 + if (!jQuery(e.target).closest("#tb-advanced-panel, #tb-advanced-toggle").length) {
1355 + jQuery("#tb-advanced-panel").removeClass("tb-open");
1356 + }
1357 + }
1358 + });jQuery(document).on("click", "#tb-close-filters", function () {
1359 + jQuery("#tb-advanced-panel").removeClass("tb-open");
1360 + jQuery("#tb-backdrop").removeClass("active");
1361 + });
1362 +</script>