← All changes
|
includes/admin/tasks/open_task/wppm_open_task.php
+538
-81
5.0.4
→
6.0.6
View file →
| @@ -4,9 +4,11 @@ | ||
| 4 | 4 | } |
| 5 | 5 | |
| 6 | 6 | global $current_user,$wpdb,$wppmfunction; |
| 7 | 7 | $id = isset($_POST) && isset($_POST['id']) ? intval(sanitize_text_field(wp_unslash($_POST['id']))) : "0"; |
| 8 | +$page = isset($_POST) && isset($_POST['page']) ? sanitize_text_field(wp_unslash($_POST['page'])) : ''; | |
| 8 | 9 | $task_list_view = get_option('wppm_default_task_list_view'); |
| 10 | +$project_id = isset($_POST) && isset($_POST['project_id']) ? intval(sanitize_text_field($_POST['project_id'])) : "0"; | |
| 9 | 11 | $wppm_default_task_date = get_option('wppm_default_task_date'); |
| 10 | 12 | $wppm_task_time = get_option('wppm_task_time'); |
| 11 | 13 | $appearance_settings = get_option("wppm-ap-individual-task"); |
| 12 | 14 | $wppm_tinymce_visibility_open_task = get_option('wppm_tinymce_visibility_open_task'); |
| @@ -28,9 +30,12 @@ | ||
| 28 | 30 | if ( $auth_code && $auth_id == $auth_code ) { |
| 29 | 31 | $url_auth = true; |
| 30 | 32 | } |
| 31 | 33 | if (!(($current_user->ID && $current_user->has_cap('manage_options')) || ($wppmfunction->has_permission('view_task',$id)) || ($url_auth==true))) { ?> |
| 32 | - <div style="align-item:center;" ><h6><?php esc_attr_e( 'Unauthorized access!', 'taskbuilder' ); ?></h6></div> | |
| 34 | + <div style="text-align:center;padding:20px 0;"> | |
| 35 | + <h6><?php esc_attr_e( 'Unauthorized access!', 'taskbuilder' ); ?></h6> | |
| 36 | + <a href="<?php echo esc_url( admin_url('admin.php?page=wppm-tasks') ); ?>" class="btn btn-success btn-sm"><?php esc_html_e( 'Go to Task List', 'taskbuilder' ); ?></a> | |
| 37 | + </div> | |
| 33 | 38 | <?php |
| 34 | 39 | wp_die(); |
| 35 | 40 | } |
| 36 | 41 | $proj_id = isset($_POST) && isset($_POST['proj_id']) ? intval(sanitize_text_field(wp_unslash($_POST['proj_id']))) : 0; |
| @@ -198,15 +203,23 @@ | ||
| 198 | 203 | }else{ |
| 199 | 204 | $archive_style= "display:none;"; |
| 200 | 205 | } |
| 201 | 206 | if($proj_id==0) { |
| 202 | - ?> <span onclick="wppm_add_new_task(<?php echo esc_attr($proj_id) ?>)" class="wppm_add_new_task_btn" id="wppm_add_new_task_btn" style="<?php echo esc_attr($style)?>" title="<?php esc_attr_e( 'Create Task', 'taskbuilder' ); ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/plus.svg'); ?>" alt="add"></span> | |
| 207 | + ?> <span onclick="wppm_add_new_task(<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)" class="wppm_add_new_task_btn" id="wppm_add_new_task_btn" style="<?php echo esc_attr($style)?>" title="<?php esc_attr_e( 'Create Task', 'taskbuilder' ); ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/plus.svg'); ?>" alt="add"></span> | |
| 203 | 208 | <?php } |
| 204 | 209 | else{ ?> |
| 205 | 210 | <span class="wppm_add_new_task_btn" id="wppm_add_new_task_btn" title="<?php esc_attr_e( '"Create Task', 'taskbuilder' ); ?>" onclick="wppm_create_project_task(<?php echo esc_attr($proj_id) ?>)" style="<?php echo esc_attr($style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/plus.svg'); ?>" alt="add"></span> |
| 206 | 211 | <?php } ?> |
| 207 | - <?php if($proj_id==0) { | |
| 208 | - $task_list_function = ($task_list_view==1)?"wppm_get_task_list()":"wppm_view_task_search_filter()"; | |
| 212 | + <?php if($proj_id==0) { | |
| 213 | + if (($project_id!=0)) { | |
| 214 | + $task_list_function = "wppm_get_project_tasks_kanban_view( {$project_id})"; | |
| 215 | + } | |
| 216 | + if (empty($project_id) && $task_list_view == 1) { | |
| 217 | + $task_list_function = "wppm_get_task_list('', {$project_id})"; | |
| 218 | + } | |
| 219 | + if(empty($task_list_view) && empty($project_id)) { | |
| 220 | + $task_list_function = "wppm_view_task_search_filter('', '', {$project_id})"; | |
| 221 | + } | |
| 209 | 222 | ?> |
| 210 | 223 | <span class="wppm-task-list-btn" id="wppm_task_list_btn" title="<?php esc_attr_e( 'Task List', 'taskbuilder' ); ?>"onclick="<?php echo esc_attr($task_list_function) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/list.svg'); ?>" alt="list"></span> |
| 211 | 224 | <?php } |
| 212 | 225 | else{ |
| @@ -212,15 +225,18 @@ | ||
| 212 | 225 | else{ |
| 213 | 226 | ?> |
| 214 | 227 | <span class="wppm-task-list-btn" id="wppm_task_list_btn" title="<?php esc_attr_e( 'Task List', 'taskbuilder' ); ?>" onclick="wppm_get_project_tasks(<?php echo esc_attr($proj_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/list.svg'); ?>" alt="list"></span> |
| 215 | 228 | <?php } ?> |
| 216 | - <?php $style = (($current_user->ID && $current_user->has_cap('manage_options')) || ($wppmfunction->has_permission('delete_task',$id)) || $wppm_current_user_capability == 'wppm_admin'|| $project_data['created_by']==$current_user->ID )? "display:inline":"display:none"; ?> | |
| 217 | - <?php $clone_style = ((($current_user->ID && $current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin') || ($wppmfunction->has_permission('clone_task',$id)) || $project_data['created_by']==$current_user->ID ) && $task->is_archived!=1) ? "display:inline":"display:none"; ?> | |
| 229 | + <?php $style = ((($current_user->ID && $current_user->has_cap('manage_options')) || ($wppmfunction->has_permission('delete_task',$id)) || $wppm_current_user_capability == 'wppm_admin'|| $project_data['created_by']==$current_user->ID ) && $user_role != 3) ? "display:inline":"display:none"; ?> | |
| 230 | + <?php $clone_style = ((($current_user->ID && $current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin') || ($wppmfunction->has_permission('clone_task',$id)) || $project_data['created_by']==$current_user->ID ) && $task->is_archived!=1 && $user_role != 3) ? "display:inline":"display:none"; ?> | |
| 218 | 231 | <?php $ar_css = ($task->is_archived==1) ? "display:none;" : "display:inline"; ?> |
| 219 | - <span class="wppm-delete_task_btn" id="wppm_delete_task_btn" title="Delete Task" onclick="wppm_get_delete_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)" style="<?php echo esc_attr($style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/bin.svg'); ?>" alt="delete"></span> | |
| 220 | - <div class="wppm-clone_task_btn" id="wppm_clone_task_btn" title="Clone Task" onclick="wppm_clone_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id)?>)" style="<?php echo esc_attr($clone_style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/duplicate.svg'); ?>" alt="clone"></div> | |
| 232 | + <span class="wppm-dashboard-btn" id="wppm_dashboard_btn" title="<?php esc_attr_e( 'Dashboard', 'taskbuilder' ); ?>" onclick="wppm_get_project_tasks(<?php echo esc_attr($proj_id) ?>)"> | |
| 233 | + <a href="<?php echo esc_url(admin_url('admin.php?page=wppm-dashboard')); ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/dashboard-icon.svg'); ?>" alt="dashboard"></a> | |
| 234 | + </span> | |
| 235 | + <span class="wppm-delete_task_btn" id="wppm_delete_task_btn" title="Delete Task" onclick="wppm_get_delete_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)" style="<?php echo esc_attr($style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/bin.svg'); ?>" alt="delete"></span> | |
| 236 | + <span class="wppm-clone_task_btn" id="wppm_clone_task_btn" title="Clone Task" onclick="wppm_clone_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id)?>,<?php echo esc_attr($project_id) ?>)" style="<?php echo esc_attr($clone_style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/duplicate.svg'); ?>" alt="clone"></span> | |
| 221 | 237 | <span class="wppm-print_task_btn" id="wppm_print_task_btn" title="Print Task" onclick="wppm_print_task(<?php echo esc_attr($id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/printer_menu.svg'); ?>" alt="print" style="<?php echo esc_attr($ar_css);?>"></span> |
| 222 | - <span class="wppm-archieve_task_btn" id="wppm_archieve_task_btn" title="<?php echo ($task->is_archived==1 ) ? 'Restore Task' : 'Archive Task'; ?>" onclick="wppm_archive_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($task->is_archived) ?>)" style="<?php echo esc_attr($archive_style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/archive.svg'); ?>" alt="archive"></span> | |
| 238 | + <span class="wppm-archieve_task_btn" id="wppm_archieve_task_btn" title="<?php echo ($task->is_archived==1 ) ? 'Restore Task' : 'Archive Task'; ?>" onclick="wppm_archive_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($task->is_archived) ?>,<?php echo esc_attr($project_id) ?>)" style="<?php echo esc_attr($archive_style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/archive.svg'); ?>" alt="archive"></span> | |
| 223 | 239 | <input type="hidden" name="wppm_archive_task_ajax_nonce" id="wppm_archive_task_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_archive_task_ajax_nonce' ) ); ?>"> |
| 224 | 240 | <div class="menu" id="wppmprint_menu" onclick="event.stopPropagation();"> |
| 225 | 241 | <a href="#" id="wppm_openPDF" onclick="wppm_open_pdf(<?php echo esc_attr($id) ?>)">🖨️ <?php echo esc_html_e('Open In Browser','taskbuilder');?></a> |
| 226 | 242 | <a href="#" id="wppm_downloadPDF" onclick="wppm_download_pdf(<?php echo esc_attr($id) ?>)">💾 <?php echo esc_html_e('Download PDF','taskbuilder');?></a> |
| @@ -225,9 +241,9 @@ | ||
| 225 | 241 | <a href="#" id="wppm_openPDF" onclick="wppm_open_pdf(<?php echo esc_attr($id) ?>)">🖨️ <?php echo esc_html_e('Open In Browser','taskbuilder');?></a> |
| 226 | 242 | <a href="#" id="wppm_downloadPDF" onclick="wppm_download_pdf(<?php echo esc_attr($id) ?>)">💾 <?php echo esc_html_e('Download PDF','taskbuilder');?></a> |
| 227 | 243 | </div> |
| 228 | 244 | <?php do_action('wppm_individual_task_button',$id);?> |
| 229 | - </div> | |
| 245 | + </div> | |
| 230 | 246 | </div> |
| 231 | 247 | <div id="wppm_load_individual_task_container" class="row"> |
| 232 | 248 | <div class="col-sm-8 wppm_body col-md-9"> |
| 233 | 249 | <div class="wppm_task_details_container"> |
| @@ -234,11 +250,26 @@ | ||
| 234 | 250 | <div class="row"> |
| 235 | 251 | <div class="col-sm-12"> |
| 236 | 252 | <span class="wppm_task_label"> <?php echo isset($task->task_name) ? esc_html($task->task_name ):"" ?> |
| 237 | 253 | <?php if (($wppmfunction->has_permission('change_task_details',$id) || $current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin') && $task->is_archived!=1) { ?> |
| 238 | - <span id="wppm_individual_edit_task_subject" onclick="wppm_edit_task_details(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)" class="btn btn-sm wppm_action_btn" style="background-color:#FFFFFF !important;color:#000000 !important;"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span> | |
| 254 | + <span id="wppm_individual_edit_task_subject" onclick="wppm_edit_task_details(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)" class="btn btn-sm wppm_action_btn" style="background-color:#FFFFFF !important;color:#000000 !important;"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span> | |
| 239 | 255 | <?php } ?> |
| 240 | 256 | </span> |
| 257 | + <?php if(!empty($task->parent_task_id)){ | |
| 258 | + $wppm_parent_task = $wpdb->get_row( $wpdb->prepare("SELECT id, task_name FROM {$wpdb->prefix}wppm_task where id=%d",absint($task->parent_task_id))); | |
| 259 | + if(!empty($wppm_parent_task)){ | |
| 260 | + $wppm_can_convert_subtask = (($current_user->has_cap('manage_options') || $wppmfunction->has_permission('delete_task',$id)) && $task->is_archived!=1); | |
| 261 | + ?> | |
| 262 | + <div class="wppm_subtask_parent_link"> | |
| 263 | + <?php echo esc_html_e('Subtask of','taskbuilder');?> | |
| 264 | + <a href="#" onclick="wppm_open_subtask(<?php echo esc_attr($wppm_parent_task->id) ?>,<?php echo esc_attr($proj_id) ?>);return false;"><?php echo esc_html($wppm_parent_task->task_name); ?></a> | |
| 265 | + <?php if($wppm_can_convert_subtask){ ?> | |
| 266 | + | <a href="#" onclick="wppm_convert_subtask_to_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>);return false;"><?php echo esc_html_e('Convert to Task','taskbuilder');?></a> | |
| 267 | + <input type="hidden" name="wppm_convert_subtask_to_task_ajax_nonce" id="wppm_convert_subtask_to_task_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_convert_subtask_to_task' ) ); ?>"> | |
| 268 | + <?php } ?> | |
| 269 | + </div> | |
| 270 | + <?php } | |
| 271 | + } ?> | |
| 241 | 272 | </div> |
| 242 | 273 | </div> |
| 243 | 274 | <div class="row"> |
| 244 | 275 | <div class="col-sm-3"> |
| @@ -329,8 +360,168 @@ | ||
| 329 | 360 | </div> |
| 330 | 361 | </div> |
| 331 | 362 | <?php do_action('wppm_after_task_details_in_open_task',$task->id, $task->project);?> |
| 332 | 363 | </div> |
| 364 | + <?php if(empty($task->parent_task_id)){ | |
| 365 | + $wppm_subtasks = $wppmfunction->get_subtasks($task_id); | |
| 366 | + $wppm_subtask_progress = $wppmfunction->get_subtask_progress($task_id); | |
| 367 | + $wppm_default_task_status = get_option('wppm_default_task_status'); | |
| 368 | + $wppm_can_add_subtask = (($current_user->has_cap('manage_options') || $wppmfunction->has_permission('add_new_task',$task_id)) && $task->is_archived!=1 && $user_role != 3); | |
| 369 | + ?> | |
| 370 | + <div class="wppm_task_subtask_container" id="wppm_task_subtask_container"> | |
| 371 | + <div class="row"> | |
| 372 | + <div class="col-sm-8"> | |
| 373 | + <span class="wppm_checklist_label"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/task_list.svg'); ?>" alt="subtasks"><?php echo esc_html_e('Subtasks','taskbuilder');?></span> | |
| 374 | + </div> | |
| 375 | + </div> | |
| 376 | + <?php if($wppm_subtask_progress['total'] > 0){ | |
| 377 | + $wppm_subtask_percent = round(($wppm_subtask_progress['completed'] / $wppm_subtask_progress['total']) * 100); ?> | |
| 378 | + <div class="wppm_progress_bar_container row"> | |
| 379 | + <div class="col-sm-4"> | |
| 380 | + <span class="wppm_progressbar_label" id="wppm_subtask_progress_label"><?php echo esc_html($wppm_subtask_progress['completed'].'/'.$wppm_subtask_progress['total']); ?></span> | |
| 381 | + </div> | |
| 382 | + <div class="wppm_progress_bar col-sm-8"> | |
| 383 | + <div id="wppm_subtask_progressbar" class="wppm_checkprogress" role="progressbar" style="width: <?php echo esc_attr($wppm_subtask_percent); ?>%;background:#5ba4cf;" aria-valuemin="0" aria-valuemax="100"></div> | |
| 384 | + </div> | |
| 385 | + </div> | |
| 386 | + <?php } ?> | |
| 387 | + <input type="hidden" name="wppm_set_change_task_status_ajax_nonce" id="wppm_subtask_status_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_set_change_task_status' ) ); ?>"> | |
| 388 | + <input type="hidden" name="wppm_add_new_subtask_ajax_nonce" id="wppm_add_new_subtask_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_add_new_subtask' ) ); ?>"> | |
| 389 | + <input type="hidden" name="wppm_remove_subtask_ajax_nonce" id="wppm_remove_subtask_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_remove_subtask' ) ); ?>"> | |
| 390 | + <input type="hidden" name="wppm_convert_subtask_to_task_ajax_nonce" id="wppm_convert_subtask_to_task_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_convert_subtask_to_task' ) ); ?>"> | |
| 391 | + <ul id="wppm_subtask_items_container" class="wppm_checklist_items_container" style="list-style-type: none; padding-left:0px; margin-top:10px; margin-bottom:10px;"> | |
| 392 | + <?php if(!empty($wppm_subtasks)){ | |
| 393 | + foreach($wppm_subtasks as $subtask){ | |
| 394 | + $wppm_subtask_checked = ($subtask['status']==4) ? 'checked="checked"' : ''; | |
| 395 | + $wppm_subtask_users = !empty($subtask['users']) ? explode(",",$subtask['users']) : array(); | |
| 396 | + $wppm_subtask_can_change_status = ($current_user->has_cap('manage_options') || $wppmfunction->has_permission('change_status',$subtask['id'])) && $task->is_archived!=1; | |
| 397 | + $wppm_subtask_can_delete = ($current_user->has_cap('manage_options') || $wppmfunction->has_permission('delete_task',$subtask['id'])) && $task->is_archived!=1; | |
| 398 | + ?> | |
| 399 | + <li id="wppm_subtask_<?php echo esc_attr($subtask['id']) ?>" class="row wppm_checklist_item" style="margin-bottom:10px;font: 15px 'Helvetica Neue',Helvetica,Arial,sans-serif;"> | |
| 400 | + <div class="col-sm-8"> | |
| 401 | + <input id="wppm_subtask_checkbox_<?php echo esc_attr($subtask['id']) ?>" type="checkbox" onchange="wppm_toggle_subtask_status(<?php echo esc_attr($subtask['id']) ?>,<?php echo esc_attr($task_id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($wppm_default_task_status) ?>,this.checked)" <?php echo esc_attr($wppm_subtask_checked) ?> <?php echo $wppm_subtask_can_change_status ? '' : 'disabled'; ?> style="margin:5px;"> | |
| 402 | + <label style="padding-top: 5px;font-weight: normal;font: 13px 'Helvetica Neue',Helvetica,Arial,sans-serif;cursor:pointer;" onclick="wppm_open_subtask(<?php echo esc_attr($subtask['id']) ?>,<?php echo esc_attr($proj_id) ?>)"><?php echo esc_html($subtask['task_name']); ?></label> | |
| 403 | + </div> | |
| 404 | + <div class="col-sm-4" style="text-align:right;"> | |
| 405 | + <?php $wppm_subtask_avatar_count = 0; | |
| 406 | + $wppm_subtask_total_users = count( array_filter( $wppm_subtask_users ) ); | |
| 407 | + foreach($wppm_subtask_users as $wppm_subtask_user_id){ | |
| 408 | + if(!$wppm_subtask_user_id) continue; | |
| 409 | + $wppm_subtask_avatar_count++; | |
| 410 | + if($wppm_subtask_avatar_count > 3) break; | |
| 411 | + $wppm_subtask_user_data = get_userdata($wppm_subtask_user_id); | |
| 412 | + $wppm_subtask_user_name = !empty($wppm_subtask_user_data) ? $wppm_subtask_user_data->display_name : ''; | |
| 413 | + echo get_avatar($wppm_subtask_user_id, 20, "mysteryman", $wppm_subtask_user_name, array('extra_attr' => 'title="'.esc_attr($wppm_subtask_user_name).'"')); | |
| 414 | + } | |
| 415 | + $wppm_subtask_more_users = $wppm_subtask_total_users - 3; | |
| 416 | + if ( $wppm_subtask_more_users > 0 ) { | |
| 417 | + ?> | |
| 418 | + <span class="wppm_subtask_more_users" title="<?php echo esc_attr( sprintf( _n( '%d more user assigned', '%d more users assigned', $wppm_subtask_more_users, 'taskbuilder' ), $wppm_subtask_more_users ) ); ?>">+<?php echo esc_html( $wppm_subtask_more_users ); ?></span> | |
| 419 | + <?php | |
| 420 | + } ?> | |
| 421 | + <?php if($wppm_subtask_can_delete){ ?> | |
| 422 | + <a href="#" title="<?php echo esc_attr__('Convert to Task','taskbuilder'); ?>" onclick="wppm_convert_subtask_to_task(<?php echo esc_attr($subtask['id']) ?>,<?php echo esc_attr($task_id) ?>,<?php echo esc_attr($proj_id) ?>);return false;" style="font-size:11px;margin-right:8px;"><?php echo esc_html_e('Convert to Task','taskbuilder');?></a> | |
| 423 | + <span onclick="wppm_delete_subtask(<?php echo esc_attr($subtask['id']) ?>,<?php echo esc_attr($task_id) ?>,<?php echo esc_attr($proj_id) ?>)" style="cursor:pointer;"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/trash.svg'); ?>" alt="delete"></span> | |
| 424 | + <?php } ?> | |
| 425 | + </div> | |
| 426 | + </li> | |
| 427 | + <?php | |
| 428 | + } | |
| 429 | + } ?> | |
| 430 | + </ul> | |
| 431 | + <?php if($wppm_can_add_subtask){ | |
| 432 | + $wppm_all_task_statuses = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wppm_task_statuses ORDER BY load_order ASC"); | |
| 433 | + ?> | |
| 434 | + <div class="row"> | |
| 435 | + <div class="col-sm-12" style="padding-top:15px;"> | |
| 436 | + <a class="wppm_add_checklist" id="wppm_add_subtask_btn" onclick="wppm_show_add_subtask()"><?php echo esc_html_e('+ Add subtask','taskbuilder');?></a> | |
| 437 | + </div> | |
| 438 | + </div> | |
| 439 | + <div class="row"> | |
| 440 | + <div class="col-sm-12" style="display:none;" id="wppm_add_subtask_label_container"> | |
| 441 | + <div class="row"> | |
| 442 | + <div class="wppm_task_frm_fields col-sm-6"> | |
| 443 | + <span class="wppm_form_field_label"><b><?php echo esc_html_e('Subtask Name','taskbuilder');?></b> <span style="color:#ff0000;">*</span></span><br> | |
| 444 | + <input type="text" id="wppm_subtask_label" class="form-control" placeholder="<?php echo esc_attr__('Subtask name','taskbuilder') ?>" name="wppm_subtask_label"> | |
| 445 | + </div> | |
| 446 | + <div class="wppm_task_frm_fields col-sm-6"> | |
| 447 | + <span class="wppm_form_field_label"><b><?php echo esc_html_e('Status','taskbuilder');?></b></span><br> | |
| 448 | + <select id="wppm_subtask_status" name="wppm_subtask_status" class="form-control"> | |
| 449 | + <?php if(!empty($wppm_all_task_statuses)){ | |
| 450 | + foreach($wppm_all_task_statuses as $wppm_st){ ?> | |
| 451 | + <option value="<?php echo esc_attr($wppm_st->id) ?>" <?php selected($wppm_st->id, $wppm_default_task_status); ?>><?php echo esc_html($wppm_st->name) ?></option> | |
| 452 | + <?php } | |
| 453 | + } ?> | |
| 454 | + </select> | |
| 455 | + </div> | |
| 456 | + </div> | |
| 457 | + <div class="row"> | |
| 458 | + <div class="wppm_task_frm_fields col-sm-6"> | |
| 459 | + <span class="wppm_form_field_label"><b><?php echo esc_html_e('Due date','taskbuilder');?></b></span><br> | |
| 460 | + <input type="text" id="wppm_subtask_due_date" class="form-control" name="wppm_subtask_due_date" value="" autocomplete="off"> | |
| 461 | + </div> | |
| 462 | + <div class="wppm_task_frm_fields col-sm-6"> | |
| 463 | + <span class="wppm_form_field_label"><b><?php echo esc_html_e('Assignee','taskbuilder');?></b></span><br> | |
| 464 | + <input class="form-control wppm_subtask_assign_users ui-autocomplete-input" name="wppm_subtask_assign_users" type="text" autocomplete="off" placeholder="<?php echo esc_attr__('Search User...','taskbuilder');?>"> | |
| 465 | + </div> | |
| 466 | + </div> | |
| 467 | + <div class="row"> | |
| 468 | + <div class="col-sm-12"> | |
| 469 | + <ul class="wppm_subtask_filter_display_users_container" style="list-style:none;padding-left:0;"></ul> | |
| 470 | + </div> | |
| 471 | + </div> | |
| 472 | + <div class="row"> | |
| 473 | + <div class="wppm_task_frm_fields col-sm-12"> | |
| 474 | + <span class="wppm_form_field_label"><b><?php echo esc_html_e('Description','taskbuilder');?></b></span><br> | |
| 475 | + <textarea id="wppm_subtask_description" name="wppm_subtask_description" class="form-control" rows="3"></textarea> | |
| 476 | + </div> | |
| 477 | + </div> | |
| 478 | + <div class="row" style="padding-top:10px;"> | |
| 479 | + <div class="col-sm-12"> | |
| 480 | + <input type="button" value="<?php echo esc_attr__('Add','taskbuilder') ?>" class="btn btn-success btn-sm" onclick="wppm_add_new_subtask(<?php echo esc_attr($task_id)?>,<?php echo esc_attr($proj_id) ?>)"> | |
| 481 | + <button type="button" class="wppm_reset_btn" onclick="wppm_hide_add_subtask()"><?php echo esc_html_e('Cancel','taskbuilder');?></button> | |
| 482 | + </div> | |
| 483 | + </div> | |
| 484 | + </div> | |
| 485 | + </div> | |
| 486 | + <script type="text/javascript"> | |
| 487 | + jQuery(document).ready(function(){ | |
| 488 | + jQuery('#wppm_subtask_due_date').flatpickr({ | |
| 489 | + enableTime: true, | |
| 490 | + dateFormat: "Y-m-d H:i" | |
| 491 | + }); | |
| 492 | + jQuery('.wppm_subtask_assign_users').autocomplete({ | |
| 493 | + minLength: 1, | |
| 494 | + appendTo: jQuery('.wppm_subtask_assign_users').parent(), | |
| 495 | + source: function(request, response){ | |
| 496 | + jQuery.getJSON(wppm_admin.ajax_url, { | |
| 497 | + action: 'wppm_filter_autocomplete', | |
| 498 | + term: request.term, | |
| 499 | + field: 'task_users_by_project_name', | |
| 500 | + proj_id: <?php echo (int) $task->project; ?> | |
| 501 | + }, function(data){ response(data); }); | |
| 502 | + }, | |
| 503 | + select: function(event, ui){ | |
| 504 | + if(!ui.item.user_id){ return false; } | |
| 505 | + var html_str = '<li class="wppm_filter_display_element" style="list-style:none">' | |
| 506 | + +'<div class="flex-container">' | |
| 507 | + +'<div class="wppm_filter_display_text">' | |
| 508 | + + ui.item.label | |
| 509 | + + '<input type="hidden" name="wppm_subtask_user_names[]" value="'+ui.item.user_id+'">' | |
| 510 | + +'</div>' | |
| 511 | + +'<div class="wppm_filter_display_remove" onclick="wppm_remove_subtask_user(this);"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/cross.svg'); ?>" alt="delete"></div>' | |
| 512 | + +'</div>' | |
| 513 | + +'</li>'; | |
| 514 | + jQuery('.wppm_subtask_filter_display_users_container').append(html_str); | |
| 515 | + jQuery(this).val(''); | |
| 516 | + return false; | |
| 517 | + } | |
| 518 | + }).focus(function(){ jQuery(this).autocomplete("search", ""); }); | |
| 519 | + }); | |
| 520 | + </script> | |
| 521 | + <?php } ?> | |
| 522 | + </div> | |
| 523 | + <?php } ?> | |
| 333 | 524 | <div class="wppm_task_checklist_container" id="wppm_task_checklist_container"> |
| 334 | 525 | <div id="wppm_checklist_container"> |
| 335 | 526 | <?php |
| 336 | 527 | if(!empty($wppm_checklist)){ |
| @@ -421,28 +612,30 @@ | ||
| 421 | 612 | <?php |
| 422 | 613 | } |
| 423 | 614 | } ?> |
| 424 | 615 | </div><?php |
| 425 | - if(($wppmfunction->has_permission('add_checklist',$task->id) || $current_user->has_cap('manage_options')) && $task->is_archived!=1){ ?> | |
| 426 | - <div id="wppm_add_checklist_container"> | |
| 427 | - <div class="row"> | |
| 428 | - <div class="col-sm-12"> | |
| 429 | - <span id="wppm_add_checklist" onclick="wppm_add_checklist()"> <?php echo esc_html_e('+Add a checklist','taskbuilder')?> </span> | |
| 616 | + if($user_role != 3){ | |
| 617 | + if(($wppmfunction->has_permission('add_checklist',$task->id) || $current_user->has_cap('manage_options')) && $task->is_archived!=1){ ?> | |
| 618 | + <div id="wppm_add_checklist_container"> | |
| 619 | + <div class="row"> | |
| 620 | + <div class="col-sm-12"> | |
| 621 | + <span id="wppm_add_checklist" onclick="wppm_add_checklist()"> <?php echo esc_html_e('+Add a checklist','taskbuilder')?> </span> | |
| 622 | + </div> | |
| 430 | 623 | </div> |
| 431 | - </div> | |
| 432 | - <div class="row" id="wppm_add_new_checklist" style="display:none;"> | |
| 433 | - <div class="col-sm-12"> | |
| 434 | - <input type="text" class="wppm_checklist_label" placeholder="<?php echo esc_attr__('Please insert checklist title','taskbuilder');?>" id="wppm_checklist_label" name="wppm_checklist_label"> | |
| 435 | - <input type="button" value="Add" id="wppm_checklist_btn" class="btn btn-success btn-sm" onclick="wppm_add_new_checklist(<?php echo esc_attr($id)?>,<?php echo esc_attr($proj_id) ?>)"> | |
| 436 | - <input type="hidden" name="wppm_checklist_ajax_nonce" id="wppm_checklist_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_add_new_checklist' ) ); ?>"> | |
| 437 | - <span onclick="wppm_remove_add_checklist()"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/cross1.svg'); ?>"></span> | |
| 624 | + <div class="row" id="wppm_add_new_checklist" style="display:none;"> | |
| 625 | + <div class="col-sm-12"> | |
| 626 | + <input type="text" class="wppm_checklist_label" placeholder="<?php echo esc_attr__('Please insert checklist title','taskbuilder');?>" id="wppm_checklist_label" name="wppm_checklist_label"> | |
| 627 | + <input type="button" value="Add" id="wppm_checklist_btn" class="btn btn-success btn-sm" onclick="wppm_add_new_checklist(<?php echo esc_attr($id)?>,<?php echo esc_attr($proj_id) ?>)"> | |
| 628 | + <input type="hidden" name="wppm_checklist_ajax_nonce" id="wppm_checklist_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_add_new_checklist' ) ); ?>"> | |
| 629 | + <span onclick="wppm_remove_add_checklist()"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/cross1.svg'); ?>"></span> | |
| 630 | + </div> | |
| 438 | 631 | </div> |
| 439 | - </div> | |
| 440 | - </br> | |
| 441 | - </div><?php | |
| 442 | - } ?> | |
| 632 | + </br> | |
| 633 | + </div><?php | |
| 634 | + } | |
| 635 | + }?> | |
| 443 | 636 | </div> |
| 444 | - <div id="wppm_activity_container" style="<?php echo ($wppm_task_hide_comment_section==0) ? 'display:none;' : 'display:block;' ?>"> | |
| 637 | + <div id="wppm_activity_container" style="<?php echo ($wppm_task_hide_comment_section==0 || $user_role==3) ? 'display:none;' : 'display:block;' ?>"> | |
| 445 | 638 | <div class="row"> |
| 446 | 639 | <div class="col-sm-12" style="margin-top:5px;"> |
| 447 | 640 | <span class="wppm_task_discussion"><?php echo esc_html_e('Comment','taskbuilder')?></span><br> |
| 448 | 641 | </div> |
| @@ -470,9 +663,9 @@ | ||
| 470 | 663 | <div class="wppm_attachment_container col-sm-12" style="display:none;"> |
| 471 | 664 | </div> |
| 472 | 665 | </div> |
| 473 | 666 | </div> |
| 474 | - <div class="wppm_thread_container" style="<?php echo ($wppm_task_hide_comment_section==0) ? 'display:none;' : 'display:block;' ?>"> | |
| 667 | + <div class="wppm_thread_container" style="<?php echo ($wppm_task_hide_comment_section==0 || $user_role==3) ? 'display:none;' : 'display:block;' ?>"> | |
| 475 | 668 | <?php |
| 476 | 669 | if(!empty($task_comment)){ |
| 477 | 670 | foreach($task_comment as $comment){ |
| 478 | 671 | $task_comment_meta = $wpdb->get_row( $wpdb->prepare( |
| @@ -484,9 +677,9 @@ | ||
| 484 | 677 | absint($comment->id) |
| 485 | 678 | ) |
| 486 | 679 | ); |
| 487 | 680 | $user = get_userdata( $comment->created_by ); |
| 488 | - $comment_body = (!empty($comment->body) ? wp_kses_post(wpautop($comment->body)) : ''); | |
| 681 | + $comment_body = (!empty($comment->body) ? ($comment->body) : ''); | |
| 489 | 682 | $date = wp_date("Y-m-d H:i:s" ,strtotime($comment->create_time)); |
| 490 | 683 | $thread_date = wp_date("d F Y, h:i:s A" ,strtotime($date)); |
| 491 | 684 | $attachment_ids = isset($comment->attachment_ids)? $comment->attachment_ids : ''; |
| 492 | 685 | if($attachment_ids!=""){ |
| @@ -574,11 +767,16 @@ | ||
| 574 | 767 | </div> |
| 575 | 768 | </div> |
| 576 | 769 | <div class="wppm_thread_messege" style="color:<?php echo esc_attr($appearance_settings['comment-secondary-color']);?>"> |
| 577 | 770 | <?php |
| 578 | - $allowedtags = array( 'br' => array(), 'abbr' => array('title' => array(),), 'p' => array(), 'strong' => array(), 'a' => array('href' => array(), 'title' => array(), 'target'=> array(), 'rel'=>array()),'em' =>array(),'span' =>array(), 'blockquote'=>array('cite' => array(),),'div' => array('class' => array(),'title' => array(),'style' => array(),),'ul'=>array(),'li'=>array(),'ol'=>array(),'img' => array( 'alt'=> array(),'class' => array(),'height' => array(),'src'=> array(),'width'=> array(),)); | |
| 771 | + $allowedtags = array( 'br' => array(), 'abbr' => array('title' => array(),), 'p' => array(), 'strong' => array(), 'a' => array('href' => array(), 'title' => array(), 'target'=> array(), 'rel'=>array()),'em' =>array(),'span' =>array('class' => true, | |
| 772 | + 'data-user-id' => true,'data-username' => true,), 'blockquote'=>array('cite' => array(),),'div' => array('class' => array(),'title' => array(),'style' => array(),),'ul'=>array(),'li'=>array(),'ol'=>array(),'img' => array( 'alt'=> array(),'class' => array(),'height' => array(),'src'=> array(),'width'=> array(),)); | |
| 579 | 773 | if(!empty($comment_body) && ((empty($task_comment_meta->comment_type)) || (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='comment') || (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='delete_task_comment'))){ |
| 580 | - echo wp_kses(wpautop($comment_body),$allowedtags); | |
| 774 | + $comment_body = $wppmfunction->wppm_clean_mentions_html($comment_body); | |
| 775 | + $comment_body = $wppmfunction->wppm_highlight_user_mentions($comment_body, $current_user->ID); | |
| 776 | + //echo wp_kses(wpautop($comment_body),$allowedtags); | |
| 777 | + //wp_kses($comment, $allowed_tags); | |
| 778 | + echo wp_kses_post(($comment_body)); | |
| 581 | 779 | } elseif(!empty($comment->body) && (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='change_task_status')){ ?> |
| 582 | 780 | <span class="wppm_admin_label" style="margin-right: 10px; background-color:<?php echo isset($task_prev_status->bg_color) ? esc_attr($task_prev_status->bg_color):""; ?>;color:<?php echo isset($task_prev_status->color) ? esc_attr($task_prev_status->color): "" ?>;"><?php echo isset($task_prev_status->name) ? esc_attr($task_prev_status->name) : "" ?></span> <img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/arrow-right.svg'); ?>" alt="arrow_right"> <span class="wppm_admin_label" style="margin-left:10px; background-color:<?php echo isset($task_new_status->bg_color) ? esc_attr($task_new_status->bg_color):""; ?>;color:<?php echo isset($task_new_status->color) ? esc_attr($task_new_status->color): "" ?>;"><?php echo isset($task_new_status->name) ? esc_attr($task_new_status->name) : "" ?></span><?php |
| 583 | 781 | }elseif(!empty($comment->body) && (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='change_task_creator')){ ?> |
| 584 | 782 | <span style="margin-right: 10px;"><?php echo isset($prev_user_data->display_name) ? esc_attr($prev_user_data->display_name) : "" ?></span> <img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/arrow-right.svg'); ?>" alt="arrow_right"> <span style="margin-left:10px;"><?php echo isset($new_user_data->display_name) ? esc_attr($new_user_data->display_name) : "" ?></span><?php |
| @@ -628,8 +826,11 @@ | ||
| 628 | 826 | if(!empty($attachments)){ |
| 629 | 827 | foreach( $attachments as $attachment ): |
| 630 | 828 | $download_url = site_url('/').'?wppm_attachment='.$attachment.'&tid='.$id.'&tac='.$auth_id; |
| 631 | 829 | $attachment = absint($attachment); |
| 830 | + if (empty($attachment)) { | |
| 831 | + continue; // or return, depending on the context | |
| 832 | + } | |
| 632 | 833 | $attach = $wpdb->get_row( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_attachments where id=%d",$attachment)); |
| 633 | 834 | $findStr = ".txt"; |
| 634 | 835 | if(!empty( $attach)){ |
| 635 | 836 | $attachment_name = preg_replace('/' . $findStr . '/', "", $attach->name, 1); |
| @@ -664,12 +865,14 @@ | ||
| 664 | 865 | <div class="row wppm_widget" id="wppm_status_widget"> |
| 665 | 866 | <div class="wppm-widget-header" style="background-color:<?php echo esc_attr($appearance_settings['widget-header-bg-color'])?>"> |
| 666 | 867 | <h4 class="widget_header" style="color:<?php echo esc_attr($appearance_settings['widget-header-text-color'])?>"><?php echo esc_html_e('Status','taskbuilder')?></h4> |
| 667 | 868 | <?php |
| 668 | - if((($current_user->has_cap('manage_options') || $wppm_current_user_capability == ('wppm_admin') || ($flag==true) || ($wppmfunction->has_permission('change_task_status',$id))!="") && ($task->is_archived!=1))){ | |
| 669 | - ?> | |
| 670 | - <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_status(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span> | |
| 671 | - <?php | |
| 869 | + if($user_role != 3){ | |
| 870 | + if((($current_user->has_cap('manage_options') || $wppm_current_user_capability == ('wppm_admin') || ($flag==true) || ($wppmfunction->has_permission('change_task_status',$id))!="") && ($task->is_archived!=1))){ | |
| 871 | + ?> | |
| 872 | + <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_status(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span> | |
| 873 | + <?php | |
| 874 | + } | |
| 672 | 875 | } |
| 673 | 876 | ?> |
| 674 | 877 | </div> |
| 675 | 878 | <hr class="widget_divider"> |
| @@ -680,11 +883,13 @@ | ||
| 680 | 883 | <div class="row wppm_widget" id="wppm_raisedby_widget"> |
| 681 | 884 | <div class="wppm-widget-header" style="background-color:<?php echo esc_attr($appearance_settings['widget-header-bg-color'])?>"> |
| 682 | 885 | <h4 class="widget_header" style="color:<?php echo esc_attr($appearance_settings['widget-header-text-color'])?>"> |
| 683 | 886 | <?php echo esc_html_e('Task Creator','taskbuilder')?></h4> |
| 684 | - <?php if ((($wppmfunction->has_permission('change_raised_by',$id ) || $current_user->has_cap('manage_options')) && ($task->is_archived!=1))) { ?> | |
| 685 | - <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_creator(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span> | |
| 686 | - <?php } ?> | |
| 887 | + <?php if($user_role != 3){ | |
| 888 | + if ((($wppmfunction->has_permission('change_raised_by',$id ) || $current_user->has_cap('manage_options')) && ($task->is_archived!=1))) { ?> | |
| 889 | + <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_creator(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span> | |
| 890 | + <?php } | |
| 891 | + }?> | |
| 687 | 892 | </div> |
| 688 | 893 | <hr class="widget_divider"> <?php |
| 689 | 894 | if(isset($task->created_by)){ |
| 690 | 895 | $user_info = get_userdata($task->created_by); |
| @@ -701,11 +906,14 @@ | ||
| 701 | 906 | </div> |
| 702 | 907 | <div class="row wppm_widget" id="wppm_task_users_widget_container"> |
| 703 | 908 | <div class="wppm-widget-header" style="background-color:<?php echo esc_attr($appearance_settings['widget-header-bg-color'])?>"> |
| 704 | 909 | <h4 class="widget_header" style="color:<?php echo esc_attr($appearance_settings['widget-header-text-color'])?>;"><?php echo esc_html_e('Users','taskbuilder')?></h4> |
| 705 | - <?php if ((($wppmfunction->has_permission('assign_task_users',$id ) || $current_user->has_cap('manage_options')) && ($task->is_archived!=1))) { ?> | |
| 706 | - <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_users(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span> | |
| 707 | - <?php } ?> | |
| 910 | + <?php | |
| 911 | + if($user_role != 3){ | |
| 912 | + if ((($wppmfunction->has_permission('assign_task_users',$id ) || $current_user->has_cap('manage_options')) && ($task->is_archived!=1))) { ?> | |
| 913 | + <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_users(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span> | |
| 914 | + <?php } | |
| 915 | + }?> | |
| 708 | 916 | </div> |
| 709 | 917 | <hr class="widget_divider"> |
| 710 | 918 | <div class="wppm-widget-body" style="background-color:<?php echo esc_attr($appearance_settings['widget-body-bg-color'])?>"> |
| 711 | 919 | <div id="wppm_task_users"> |
| @@ -768,8 +976,11 @@ | ||
| 768 | 976 | // Hide when clicking outside |
| 769 | 977 | document.addEventListener('click', () => { |
| 770 | 978 | box.style.display = 'none'; |
| 771 | 979 | }); |
| 980 | + jQuery('#wppm_task_comment').on('focus', function(){ | |
| 981 | + // showMentionList(''); | |
| 982 | + }); | |
| 772 | 983 | <?php |
| 773 | 984 | if ((($current_user->ID && $current_user->has_cap('manage_options')) || $wppmfunction->has_permission('change_task_details',$task->id))){ ?> |
| 774 | 985 | jQuery("#wppm_edit_tstart_date").flatpickr({ |
| 775 | 986 | enableTime: true, |
| @@ -832,47 +1043,59 @@ | ||
| 832 | 1043 | $italic = (isset($wppm_toolbar_actions['italic']) && $wppm_toolbar_actions['italic']==1)? 'italic' :""; |
| 833 | 1044 | $underline = (isset($wppm_toolbar_actions['underline']) && $wppm_toolbar_actions['underline']==1)?'underline' :""; |
| 834 | 1045 | $blockquote = (isset($wppm_toolbar_actions['blockquote']) && $wppm_toolbar_actions['blockquote']==1)? 'blockquote' :""; |
| 835 | 1046 | $align = (isset($wppm_toolbar_actions['align']) && $wppm_toolbar_actions['align']==1)? ' alignleft aligncenter alignright ' :""; |
| 836 | - $bullist = (isset($wppm_toolbar_actions['bullist']) && $wppm_toolbar_actions['bullist']==1)? $bullist = 'bullist' :""; | |
| 837 | - $numlist = (isset($wppm_toolbar_actions['numlist']) && $wppm_toolbar_actions['numlist']==1)? $numlist = 'numlist' :""; | |
| 838 | - $rtl = (isset($wppm_toolbar_actions['rtl']) && $wppm_toolbar_actions['rtl']==1)? $rtl = 'rtl' :""; | |
| 839 | - $link = (isset($wppm_toolbar_actions['link']) && $wppm_toolbar_actions['link']==1)? $link = 'link' :""; | |
| 840 | - $image = (isset($wppm_toolbar_actions['wppm_insert_editor_img']) && $wppm_toolbar_actions['wppm_insert_editor_img']==1)? $image = 'image' :""; | |
| 841 | - $forecolor = (isset($wppm_toolbar_actions['forecolor']) && $wppm_toolbar_actions['forecolor']==1)? $forecolor = 'forecolor' :""; | |
| 842 | - $backcolor = (isset($wppm_toolbar_actions['backcolor']) && $wppm_toolbar_actions['backcolor']==1)? $backcolor = 'backcolor' :""; | |
| 843 | - $strikethrough = (isset($wppm_toolbar_actions['strikethrough']) && $wppm_toolbar_actions['strikethrough']==1)? $strikethrough = 'strikethrough' :""; | |
| 1047 | + $bullist = (isset($wppm_toolbar_actions['bullist']) && $wppm_toolbar_actions['bullist']==1)? 'bullist' :""; | |
| 1048 | + $numlist = (isset($wppm_toolbar_actions['numlist']) && $wppm_toolbar_actions['numlist']==1)? 'numlist' :""; | |
| 1049 | + $rtl = (isset($wppm_toolbar_actions['rtl']) && $wppm_toolbar_actions['rtl']==1)? 'rtl' :""; | |
| 1050 | + $link = (isset($wppm_toolbar_actions['link']) && $wppm_toolbar_actions['link']==1)? 'link' :""; | |
| 1051 | + $image = (isset($wppm_toolbar_actions['wppm_insert_editor_img']) && $wppm_toolbar_actions['wppm_insert_editor_img']==1)? 'image' :""; | |
| 1052 | + $forecolor = (isset($wppm_toolbar_actions['forecolor']) && $wppm_toolbar_actions['forecolor']==1)? 'forecolor' :""; | |
| 1053 | + $backcolor = (isset($wppm_toolbar_actions['backcolor']) && $wppm_toolbar_actions['backcolor']==1)? 'backcolor' :""; | |
| 1054 | + $strikethrough = (isset($wppm_toolbar_actions['strikethrough']) && $wppm_toolbar_actions['strikethrough']==1)? 'strikethrough' :""; | |
| 844 | 1055 | $toolbar = trim("$bold $italic $underline $blockquote | $align | $bullist $numlist | $rtl | $link $image | $forecolor $backcolor $strikethrough"); |
| 845 | 1056 | if(($wppm_tinymce_visibility_open_task==1)){ ?> |
| 846 | 1057 | if((wppm_admin.rich_text_editor) && (wppm_admin.rich_text_editor.trim().length > 0) && (wppm_admin.rich_text_editor == 1)){ |
| 847 | - tinymce.remove(); | |
| 848 | - tinymce.init({ | |
| 1058 | + getMentionDropdown(editor); | |
| 1059 | + tinymce.remove(); | |
| 1060 | + tinymce.init({ | |
| 849 | 1061 | selector:'#wppm_task_comment', |
| 850 | 1062 | body_id: 'wppm_task_comment', |
| 851 | - directionality : '<?php //echo 'rtl'; ?>', | |
| 852 | 1063 | menubar: false, |
| 853 | 1064 | statusbar: false, |
| 854 | 1065 | height : '200', |
| 855 | 1066 | width : '100%', |
| 856 | - plugins: [ | |
| 857 | - 'lists link image directionality paste textcolor' | |
| 858 | - ], | |
| 859 | - image_advtab: true, | |
| 860 | - toolbar:'<?php echo esc_js( $toolbar ); ?>', | |
| 861 | - branding: false, | |
| 862 | - autoresize_bottom_margin: 20, | |
| 863 | - browser_spellcheck : true, | |
| 864 | - relative_urls : false, | |
| 865 | - remove_script_host : false, | |
| 866 | - convert_urls : true, | |
| 867 | - paste_as_text: true, | |
| 1067 | + plugins: ['lists link image directionality paste textcolor'], | |
| 1068 | + valid_elements: '*[*]', | |
| 1069 | + extended_valid_elements: 'span[class|data-username|data-user-id|,p,br,strong,em,a[href|target]contenteditable]', | |
| 1070 | + toolbar:'<?php echo esc_js($toolbar); ?>', | |
| 1071 | + content_style: ` | |
| 1072 | + .wppm-mention{ | |
| 1073 | + display:inline-block; | |
| 1074 | + background:linear-gradient(135deg,#eef2ff,#e0e7ff); | |
| 1075 | + color:#5b21b6; | |
| 1076 | + padding:2px 8px; | |
| 1077 | + border-radius:16px; | |
| 1078 | + font-weight:600; | |
| 1079 | + border:1px solid #c7d2fe; | |
| 1080 | + } | |
| 1081 | + | |
| 1082 | + .wppm-mention-me{ | |
| 1083 | + background:linear-gradient(135deg,#fef3c7,#fde68a); | |
| 1084 | + color:#92400e; | |
| 1085 | + border:1px solid #fbbf24; | |
| 1086 | + font-weight:700; | |
| 1087 | + } | |
| 1088 | + ` | |
| 868 | 1089 | setup: function (editor) { |
| 1090 | + wppmmenwppmMentionSetup(editor) | |
| 1091 | + | |
| 1092 | + } // ✅ only ONE setup | |
| 1093 | + }); | |
| 1094 | + jQuery('#wppm_comment_btn').show(); | |
| 869 | 1095 | } |
| 870 | - }); | |
| 871 | - jQuery('#wppm_comment_btn').show(); | |
| 872 | - } | |
| 873 | - <?php } ?> | |
| 874 | -}); | |
| 1096 | + <?php } ?> | |
| 1097 | + }); | |
| 875 | 1098 | |
| 876 | 1099 | jQuery(function(jQuery){ |
| 877 | 1100 | // Checklist Sorting |
| 878 | 1101 | jQuery(".wppm_checklist_items_container").sortable({ |
| @@ -947,8 +1170,9 @@ | ||
| 947 | 1170 | remove_script_host : false, |
| 948 | 1171 | convert_urls : true, |
| 949 | 1172 | paste_as_text: true, |
| 950 | 1173 | setup: function (editor) { |
| 1174 | + wppmMentionSetup(editor); | |
| 951 | 1175 | } |
| 952 | 1176 | }); |
| 953 | 1177 | } else{ |
| 954 | 1178 | jQuery('#wppm_task_comment').css("width", "100%"); |
| @@ -957,18 +1181,30 @@ | ||
| 957 | 1181 | } |
| 958 | 1182 | jQuery('#wppm_comment_btn').show(); |
| 959 | 1183 | } |
| 960 | 1184 | |
| 961 | -function wppm_submit_task_comment(id,proj_id){ | |
| 1185 | +function wppm_submit_task_comment(id, proj_id){ | |
| 1186 | + jQuery('#wppm_mention_list').remove(); | |
| 962 | 1187 | var dataform = new FormData(jQuery('#wppm_open_task')[0]); |
| 963 | 1188 | dataform.append('action','wppm_submit_task_comment'); |
| 964 | - if((wppm_admin.rich_text_editor == 1)){ | |
| 965 | - var comment_body = tinyMCE.get('wppm_task_comment').getContent().trim(); | |
| 966 | - } else{ | |
| 967 | - var comment_body = jQuery("#wppm_task_comment").val(); | |
| 1189 | + let comment_body; | |
| 1190 | + if(wppm_admin.rich_text_editor == 1){ | |
| 1191 | + const editor = tinyMCE.get('wppm_task_comment'); | |
| 1192 | + // Remove dropdown from TinyMCE iframe | |
| 1193 | + const dropdown = editor.getDoc().getElementById('wppm_mention_list'); | |
| 1194 | + if (dropdown) { | |
| 1195 | + dropdown.remove(); | |
| 1196 | + } | |
| 1197 | + comment_body = editor.getContent().trim(); | |
| 1198 | + //comment_body = tinyMCE.get('wppm_task_comment').getContent().trim(); | |
| 1199 | + // remove mention dropdown if accidentally inserted | |
| 1200 | + //comment_body = comment_body.replace(/<div[^>]*id="wppm_mention_list"[^>]*>.*?<\/div>/gi, ''); | |
| 1201 | + comment_body = comment_body.replace( /<div class="mention-item"[\s\S]*?<\/div>/g, ''); | |
| 1202 | + } else { | |
| 1203 | + comment_body = jQuery("#wppm_task_comment").val(); | |
| 968 | 1204 | } |
| 969 | - dataform.append('comment_body',comment_body); | |
| 970 | - dataform.append('task_id',id); | |
| 1205 | + dataform.append('comment_body', comment_body); | |
| 1206 | + dataform.append('task_id', id); | |
| 971 | 1207 | jQuery('#wppm_task_container').html(wppm_admin.loading_html); |
| 972 | 1208 | jQuery.ajax({ |
| 973 | 1209 | url: wppm_admin.ajax_url, |
| 974 | 1210 | type: 'POST', |
| @@ -975,12 +1211,12 @@ | ||
| 975 | 1211 | data: dataform, |
| 976 | 1212 | processData: false, |
| 977 | 1213 | contentType: false |
| 978 | 1214 | }) |
| 979 | - .done(function (response_str) { | |
| 980 | - if((proj_id!=0)||(proj_id!="")){ | |
| 981 | - wppm_open_project_tasks(id,proj_id); | |
| 982 | - }else if((proj_id==0)||(proj_id=="")){ | |
| 1215 | + .done(function () { | |
| 1216 | + if (proj_id != 0 && proj_id != "") { | |
| 1217 | + wppm_open_project_tasks(id, proj_id); | |
| 1218 | + } else { | |
| 983 | 1219 | wppm_open_task(id); |
| 984 | 1220 | } |
| 985 | 1221 | }); |
| 986 | 1222 | } |
| @@ -1076,6 +1312,227 @@ | ||
| 1076 | 1312 | }); |
| 1077 | 1313 | } |
| 1078 | 1314 | }); |
| 1079 | 1315 | jQuery('#wppm_attachment_upload').trigger('click'); |
| 1316 | +} | |
| 1317 | + | |
| 1318 | +function wppmMentionSetup(editor) { | |
| 1319 | + let mentionIndex = -1; | |
| 1320 | + editor.on('keyup', function (e) { | |
| 1321 | + editor.lastMentionRange = editor.selection.getRng(); | |
| 1322 | + let rng = editor.selection.getRng(); | |
| 1323 | + let node = rng.startContainer; | |
| 1324 | + | |
| 1325 | + if (!node || node.nodeType !== 3) return; | |
| 1326 | + | |
| 1327 | + let text = node.textContent; | |
| 1328 | + let cursorPos = rng.startOffset; | |
| 1329 | + let textBeforeCursor = text.substring(0, cursorPos); | |
| 1330 | + | |
| 1331 | + let match = textBeforeCursor.match(/@(\w*)$/); | |
| 1332 | + let dropdown = getMentionDropdown(editor); | |
| 1333 | + | |
| 1334 | + if (match) { | |
| 1335 | + let query = match[1]; | |
| 1336 | + let rect = rng.getBoundingClientRect(); | |
| 1337 | + if (!rect || rect.top === 0) { | |
| 1338 | + rect = editor.selection.getNode().getBoundingClientRect(); | |
| 1339 | + } | |
| 1340 | + let top = rect.bottom + editor.getWin().scrollY; | |
| 1341 | + let left = rect.left + editor.getWin().scrollX; | |
| 1342 | + jQuery.post(wppm_admin.ajax_url, { | |
| 1343 | + action: 'wppm_filter_autocomplete', | |
| 1344 | + term: query, | |
| 1345 | + field : 'task_user_name', | |
| 1346 | + task_id:<?php echo esc_attr($task_id) ?>, | |
| 1347 | + proj_id:<?php echo esc_attr($proj_id) ?> | |
| 1348 | + }, function (res) { | |
| 1349 | + | |
| 1350 | + if (typeof res === "string") res = JSON.parse(res); | |
| 1351 | + if (res.success) res = res.data; | |
| 1352 | + | |
| 1353 | + if (!Array.isArray(res)) return; | |
| 1354 | + | |
| 1355 | + dropdown.empty(); | |
| 1356 | + if( res.length === 0 ){ | |
| 1357 | + dropdown.hide(); | |
| 1358 | + return; | |
| 1359 | + }else{ | |
| 1360 | + res.forEach(user => { | |
| 1361 | + let item = jQuery('<div>') | |
| 1362 | + .addClass('mention-item') | |
| 1363 | + .attr('data-username', user.label) | |
| 1364 | + .attr('data-user-id', user.user_id) | |
| 1365 | + .text(user.label) | |
| 1366 | + .css({ | |
| 1367 | + padding: '8px 12px', | |
| 1368 | + cursor: 'pointer', | |
| 1369 | + fontSize: '14px', | |
| 1370 | + color: '#333', | |
| 1371 | + background: '#fff', | |
| 1372 | + borderBottom: '1px solid #eee' | |
| 1373 | + }); | |
| 1374 | + | |
| 1375 | + item.on('mouseenter', function () { | |
| 1376 | + jQuery(this).css({ | |
| 1377 | + background: '#0073aa', | |
| 1378 | + color: '#fff' | |
| 1379 | + }); | |
| 1380 | + }); | |
| 1381 | + item.on('mouseleave', function () { | |
| 1382 | + if (!jQuery(this).hasClass('active')) { | |
| 1383 | + jQuery(this).css({ | |
| 1384 | + background: '#fff', | |
| 1385 | + color: '#333' | |
| 1386 | + }); | |
| 1387 | + } | |
| 1388 | + }); | |
| 1389 | + dropdown.append(item); | |
| 1390 | + }); | |
| 1391 | + let items = dropdown.find('.mention-item'); | |
| 1392 | + items.removeClass('active').css({ | |
| 1393 | + background: '#fff', | |
| 1394 | + color: '#333' | |
| 1395 | + }); | |
| 1396 | + items.eq(0) | |
| 1397 | + .addClass('active') | |
| 1398 | + .css({ | |
| 1399 | + background: '#0073aa', | |
| 1400 | + color: '#fff' | |
| 1401 | + }); | |
| 1402 | + mentionIndex = 0; | |
| 1403 | + updateActiveItem(items.eq(0), mentionIndex); | |
| 1404 | + dropdown.css({ | |
| 1405 | + position: 'absolute', | |
| 1406 | + display: 'none', | |
| 1407 | + background: '#fff', | |
| 1408 | + border: '1px solid #ddd', | |
| 1409 | + borderRadius: '6px', | |
| 1410 | + padding: '5px 0', | |
| 1411 | + minWidth: '180px', | |
| 1412 | + maxHeight: '220px', | |
| 1413 | + overflowY: 'auto', | |
| 1414 | + boxShadow: '0 4px 10px rgba(0,0,0,.15)', | |
| 1415 | + zIndex: 999999999999999 | |
| 1416 | + }).show(); | |
| 1417 | + } | |
| 1418 | + }); | |
| 1419 | + } else { | |
| 1420 | + dropdown.hide(); | |
| 1421 | + } | |
| 1422 | + }); | |
| 1423 | + editor.on('keydown', function (e) { | |
| 1424 | + let dropdown = getMentionDropdown(editor); | |
| 1425 | + let items = dropdown.find('.mention-item'); | |
| 1426 | + | |
| 1427 | + if (!dropdown.is(':visible') || !items.length) return; | |
| 1428 | + | |
| 1429 | + // DOWN | |
| 1430 | + if (e.key === 'ArrowDown') { | |
| 1431 | + e.preventDefault(); | |
| 1432 | + mentionIndex++; | |
| 1433 | + | |
| 1434 | + if (mentionIndex >= items.length) { | |
| 1435 | + mentionIndex = 0; | |
| 1436 | + } | |
| 1437 | + updateActiveItem(items, mentionIndex); | |
| 1438 | + items.removeClass('active').css({ | |
| 1439 | + background: '#fff', | |
| 1440 | + color: '#333' | |
| 1441 | + }); | |
| 1442 | + | |
| 1443 | + items.eq(mentionIndex) | |
| 1444 | + .addClass('active') | |
| 1445 | + .css({ | |
| 1446 | + background: '#0073aa', | |
| 1447 | + color: '#fff' | |
| 1448 | + }); | |
| 1449 | + } | |
| 1450 | + | |
| 1451 | + // UP | |
| 1452 | + if (e.key === 'ArrowUp') { | |
| 1453 | + e.preventDefault(); | |
| 1454 | + mentionIndex--; | |
| 1455 | + if (mentionIndex < 0) { | |
| 1456 | + mentionIndex = items.length - 1; | |
| 1457 | + } | |
| 1458 | + updateActiveItem(items, mentionIndex); | |
| 1459 | + items.removeClass('active').css({ | |
| 1460 | + background: '#fff', | |
| 1461 | + color: '#333' | |
| 1462 | + }); | |
| 1463 | + | |
| 1464 | + items.eq(mentionIndex) | |
| 1465 | + .addClass('active') | |
| 1466 | + .css({ | |
| 1467 | + background: '#0073aa', | |
| 1468 | + color: '#fff' | |
| 1469 | + }); | |
| 1470 | + } | |
| 1471 | + // ENTER | |
| 1472 | + if (e.key === 'Enter') { | |
| 1473 | + if (mentionIndex >= 0) { | |
| 1474 | + e.preventDefault(); | |
| 1475 | + items.eq(mentionIndex).trigger('click'); | |
| 1476 | + } | |
| 1477 | + } | |
| 1478 | + // ESC | |
| 1479 | + if (e.key === 'Escape') { | |
| 1480 | + dropdown.hide(); | |
| 1481 | + mentionIndex = -1; | |
| 1482 | + } | |
| 1483 | + }); | |
| 1484 | + editor.on('click', function (e) { | |
| 1485 | + let target = jQuery(e.target); | |
| 1486 | + if (target.hasClass('mention-item')) { | |
| 1487 | + let username = target.data('username'); | |
| 1488 | + let userId = target.data('user-id'); | |
| 1489 | + | |
| 1490 | + editor.focus(); | |
| 1491 | + | |
| 1492 | + let rng = editor.lastMentionRange || editor.selection.getRng(); | |
| 1493 | + editor.selection.setRng(rng); | |
| 1494 | + | |
| 1495 | + let node = rng.startContainer; | |
| 1496 | + if (!node || node.nodeType !== 3) return; | |
| 1497 | + | |
| 1498 | + let text = node.textContent; | |
| 1499 | + let cursorPos = rng.startOffset; | |
| 1500 | + | |
| 1501 | + let lastAtIndex = text.substring(0, cursorPos).lastIndexOf('@'); | |
| 1502 | + | |
| 1503 | + if (lastAtIndex !== -1) { | |
| 1504 | + | |
| 1505 | + let range = editor.selection.getRng(); | |
| 1506 | + range.setStart(node, lastAtIndex); | |
| 1507 | + range.setEnd(node, cursorPos); | |
| 1508 | + | |
| 1509 | + editor.selection.setRng(range); | |
| 1510 | + | |
| 1511 | + editor.selection.setContent( | |
| 1512 | + '<span class="wppm-mention" contenteditable="false" data-username="' + username + '" data-user-id="' + userId + '">@' + username + '</span> ' | |
| 1513 | + ); | |
| 1514 | + } | |
| 1515 | + getMentionDropdown(editor).hide(); | |
| 1516 | + } | |
| 1517 | + }); | |
| 1518 | + | |
| 1519 | + editor.on('blur', function () { | |
| 1520 | + getMentionDropdown(editor).hide(); | |
| 1521 | + }); | |
| 1522 | + | |
| 1523 | + editor.on('init', function () { | |
| 1524 | + let body = editor.getBody(); | |
| 1525 | + if (!body) return; | |
| 1526 | + | |
| 1527 | + body.addEventListener('mousedown', function (e) { | |
| 1528 | + if (e.target.classList.contains('mention-item')) { | |
| 1529 | + e.preventDefault(); | |
| 1530 | + } | |
| 1531 | + }); | |
| 1532 | + if (!editor.mentionDropdown) { | |
| 1533 | + editor.mentionDropdown = jQuery('<div class="mention-dropdown"></div>'); | |
| 1534 | + jQuery('body').append(editor.mentionDropdown); // ✅ ONLY HERE | |
| 1535 | + } | |
| 1536 | + }); | |
| 1080 | 1537 | } |
| 1081 | 1538 | </script> |