View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0010020 | mantisbt | bugtracker | public | 2009-01-06 02:16 | 2017-07-27 02:30 |
Reporter | olegos | Assigned To | |||
Priority | normal | Severity | feature | Reproducibility | N/A |
Status | acknowledged | Resolution | open | ||
Summary | 0010020: Threading for notes | ||||
Description | It would be nice if it were possible to see issue notes in a threaded way, similarly to some web forums that support threading. I imagine each note would have a Reply button, and there would be a way to switch to a threaded view. | ||||
Tags | patch | ||||
Attached Files | bugnote-answers.patch (12,890 bytes)
Index: bugnote_add_inc.php =================================================================== --- bugnote_add_inc.php (revision 211) +++ bugnote_add_inc.php (working copy) @@ -30,6 +30,7 @@ <?php collapse_open( 'bugnote_add' ); ?> +<a name="bugnote_add"></a> <form name="bugnoteadd" method="post" action="bugnote_add.php"> <?php echo form_security_field( 'bugnote_add' ) ?> <input type="hidden" name="bug_id" value="<?php echo $f_bug_id ?>" /> @@ -70,6 +71,15 @@ </tr> <?php } ?> +<tr class="row-1"> + <td class="category"> + Parent-Bugnote-ID: + </td> + <td> + <input type="text" name="parent_bugnote_id" id="parent_bugnote_id" value="0" size="3" /> + </td> +</tr> + <?php if ( config_get('time_tracking_enabled') ) { ?> <?php if ( access_has_bug_level( config_get( 'time_tracking_edit_threshold' ), $f_bug_id ) ) { ?> <tr <?php echo helper_alternate_class() ?>> @@ -97,11 +107,7 @@ <?php } ?> <?php event_signal( 'EVENT_BUGNOTE_ADD_FORM', array( $f_bug_id ) ); ?> -<tr> - <td class="center" colspan="2"> - <input type="submit" class="button" value="<?php echo lang_get( 'add_bugnote_button' ) ?>" onclick="this.disabled=1;document.bugnoteadd.submit();" /> - </td> -</tr> + </table> </form> <?php Index: bugnote_delete.php =================================================================== --- bugnote_delete.php (revision 211) +++ bugnote_delete.php (working copy) @@ -52,6 +52,25 @@ access_ensure_bugnote_level( config_get( 'delete_bugnote_threshold' ), $f_bugnote_id ); } + $t_bugnote_table = db_get_table( 'mantis_bugnote_table' ); + $query = " SELECT * + FROM $t_bugnote_table + WHERE bug_id=" . db_param() . " AND parent_bugnote_id=" . db_param(); + $result = db_query_bound( $query, Array( $t_bug_id , $f_bugnote_id ) ); + $bugnote_count = db_num_rows( $result ); + + if($bugnote_count > 0){ + html_page_top(); + + echo "<br />\n<div align=\"center\">\n"; + print_hr(); + echo "\n" . lang_get('delete_bugnote_delete_child_bugnotes_first') . "\n"; + print_hr(); + echo "</div>\n"; + + html_page_bottom(); + exit; + }else{ helper_ensure_confirmed( lang_get( 'delete_bugnote_sure_msg' ), lang_get( 'delete_bugnote_button' ) ); @@ -63,3 +82,4 @@ form_security_purge( 'bugnote_delete' ); print_successful_redirect( string_get_bug_view_url( $t_bug_id ) . '#bugnotes' ); + } Index: bugnote_view_inc.php =================================================================== --- bugnote_view_inc.php (revision 211) +++ bugnote_view_inc.php (working copy) @@ -27,8 +27,14 @@ /** * Requires bugnote API */ + require_once( 'current_user_api.php' ); +showBugnotes($f_bug_id); + +function showBugnotes($f_bug_id, $t_parent_bugnote_id = 0){ + global $g_project_override, $tpl_bug_id, $t_bugnote; + # grab the user id currently logged in $t_user_id = auth_get_current_user_id(); @@ -41,7 +47,14 @@ # get the bugnote data $t_bugnote_order = current_user_get_pref( 'bugnote_order' ); -$t_bugnotes = bugnote_get_all_visible_bugnotes( $f_bug_id, $t_bugnote_order, 0, $t_user_id ); + if($t_parent_bugnote_id > 0){ + $t_bugnotes = bugnote_get_all_visible_bugnotes( $f_bug_id, $t_bugnote_order, 0, $t_user_id, $t_parent_bugnote_id); + if(count($t_bugnotes) < 1){ + return 0; + } + }else{ + $t_bugnotes = bugnote_get_all_visible_bugnotes( $f_bug_id, $t_bugnote_order, 0, $t_user_id, 0); + } #precache users $t_bugnote_users = array(); @@ -51,6 +64,8 @@ user_cache_array_rows( $t_bugnote_users ); $num_notes = count( $t_bugnotes ); + + if($t_parent_bugnote_id < 1){ ?> <?php # Bugnotes BEGIN ?> @@ -68,6 +83,11 @@ </td> </tr> <?php + }else{ + ?> + <table width="100%" cellspacing="1"> + <?php + } # no bugnotes if ( 0 == $num_notes ) { ?> @@ -108,11 +128,12 @@ $t_bugnote_css = 'bugnote-public'; $t_bugnote_note_css = 'bugnote-note-public'; } + ?> <tr class="bugnote" id="c<?php echo $t_bugnote->id ?>"> <td class="<?php echo $t_bugnote_css ?>"> <?php print_avatar( $t_bugnote->reporter_id ); ?> - <span class="small">(<a href="<?php echo string_get_bugnote_view_url($t_bugnote->bug_id, $t_bugnote->id) ?>" title="<?php echo lang_get( 'bugnote_link_title' ) ?>"><?php echo $t_bugnote_id_formatted ?>)</a></span><br /> + <span class="small">(<a href="<?php echo string_get_bugnote_view_url($t_bugnote->bug_id, $t_bugnote->id) ?>" title="<?php echo lang_get( 'bugnote_link_title' ) ?>"><?php echo $t_bugnote_id_formatted ?>)</a></span> <?php echo print_user( $t_bugnote->reporter_id ); ?> @@ -129,13 +150,12 @@ <span class="small">[ <?php echo lang_get( 'private' ) ?> ]</span> <?php } ?> <br /> - <span class="small"><?php echo date( $t_normal_date_format, $t_bugnote->date_submitted ); ?></span><br /> - <?php + <span class="small"><?php echo date( $t_normal_date_format, $t_bugnote->date_submitted ); ?></span><?php if ( $t_bugnote_modified ) { - echo '<span class="small">' . lang_get( 'edited_on') . lang_get( 'word_separator' ) . date( $t_normal_date_format, $t_bugnote->last_modified ) . '</span><br />'; + echo '<span class="small">, ' . lang_get( 'edited_on') . lang_get( 'word_separator' ) . date( $t_normal_date_format, $t_bugnote->last_modified ) . '</span>'; } ?> - <br /><div class="small"> + <div class="small"> <?php # bug must be open to be editable if ( !bug_is_readonly( $f_bug_id ) ) { @@ -171,6 +191,10 @@ print_button( 'bugnote_set_view_state.php?private=1&bugnote_id=' . $t_bugnote->id, lang_get( 'make_private' ) ); } } + + ?> + [<a href="#bugnote_add" onclick="document.getElementById('parent_bugnote_id').value='<?php echo $t_bugnote->id; ?>';">Antworten</a>] + <?php } ?> </div> @@ -211,29 +235,58 @@ break; } - echo string_display_links( $t_bugnote->note );; + $note = str_replace(array('<','>'), array('<','>'), $t_bugnote->note); + echo string_display_links( $note ); ?> </td> </tr> <?php event_signal( 'EVENT_VIEW_BUGNOTE', array( $f_bug_id, $t_bugnote->id, VS_PRIVATE == $t_bugnote->view_state ) ); ?> + <?php + // Child-Bugnotes + $t_childBugnotes = bugnote_get_all_visible_bugnotes( $f_bug_id, $t_bugnote_order, 0, $t_user_id, $t_bugnote->id); + if(count($t_childBugnotes) > 0){ + ?> + <tr> + <td colspan="2"> + <table width="100%" cellspacing="0"> + <tr> + <td width="10"> </td> + <td> + <?php + $t_total_time += showBugnotes($f_bug_id, $t_bugnote->id); + ?> + </td> + </tr> + </table> + </td> + </tr> + <?php + } + + if($t_parent_bugnote_id < 1){ + ?> <tr class="spacer"> <td colspan="2"></td> </tr> <?php + } + } # end for loop - if ( $t_total_time > 0 && access_has_bug_level( config_get( 'time_tracking_view_threshold' ), $f_bug_id ) ) { + if ($t_parent_bugnote_id < 1 && $t_total_time > 0 && access_has_bug_level( config_get( 'time_tracking_view_threshold' ), $f_bug_id ) ) { echo '<tr><td colspan="2">', sprintf ( lang_get( 'total_time_for_issue' ), db_minutes_to_hhmm( $t_total_time ) ), '</td></tr>'; } + if($t_parent_bugnote_id < 1){ event_signal( 'EVENT_VIEW_BUGNOTES_END', $f_bug_id ); + } ?> </table> <?php + if($t_parent_bugnote_id < 1){ collapse_closed( 'bugnotes' ); ?> - <table class="width100" cellspacing="1"> <tr> <td class="form-title" colspan="2"> @@ -244,3 +297,7 @@ </table> <?php collapse_end( 'bugnotes' ); + } + + return $t_total_time; +} \ No newline at end of file Index: core/bugnote_api.php =================================================================== --- core/bugnote_api.php (revision 211) +++ core/bugnote_api.php (working copy) @@ -125,9 +125,11 @@ * @access public */ function bugnote_add( $p_bug_id, $p_bugnote_text, $p_time_tracking = '0:00', $p_private = false, $p_type = BUGNOTE, $p_attr = '', $p_user_id = null, $p_send_email = TRUE, $p_log_history = TRUE) { + $c_bug_id = db_prepare_int( $p_bug_id ); $c_time_tracking = helper_duration_to_minutes( $p_time_tracking ); $c_type = db_prepare_int( $p_type ); + $c_parent_bugnote_id = gpc_get_int('parent_bugnote_id', 0); if( REMINDER !== $p_type ) { # Check if this is a time-tracking note @@ -176,10 +178,10 @@ # insert bugnote info $query = "INSERT INTO $t_bugnote_table - (bug_id, reporter_id, bugnote_text_id, view_state, date_submitted, last_modified, note_type, note_attr, time_tracking ) + (bug_id, parent_bugnote_id, reporter_id, bugnote_text_id, view_state, date_submitted, last_modified, note_type, note_attr, time_tracking ) VALUES - (" . db_param() . ', ' . db_param() . ',' . db_param() . ', ' . db_param() . ', ' . db_param() . ',' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ' )'; - db_query_bound( $query, Array( $c_bug_id, $c_user_id, $t_bugnote_text_id, $t_view_state, db_now(), db_now(), $c_type, $p_attr, $c_time_tracking ) ); + (" . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ',' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ' )'; + db_query_bound( $query, Array( $c_bug_id, $c_parent_bugnote_id, $c_user_id, $t_bugnote_text_id, $t_view_state, db_now(), db_now(), $c_type, $p_attr, $c_time_tracking ) ); # get bugnote id $t_bugnote_id = db_insert_id( $t_bugnote_table ); @@ -206,11 +208,13 @@ # Event integration event_signal( 'EVENT_BUGNOTE_ADD', array( $p_bug_id, $t_bugnote_id ) ); + # only send email if the text is not blank, otherwise, it is just recording of time without a comment. if( TRUE == $p_send_email && !is_blank( $t_bugnote_text ) ) { email_bugnote_add( $p_bug_id ); } + return $t_bugnote_id; } @@ -353,7 +357,7 @@ * @return array array of bugnotes * @access public */ -function bugnote_get_all_visible_bugnotes( $p_bug_id, $p_user_bugnote_order, $p_user_bugnote_limit, $p_user_id = null ) { +function bugnote_get_all_visible_bugnotes( $p_bug_id, $p_user_bugnote_order, $p_user_bugnote_limit, $p_user_id = null, $p_parent_bugnote_id = 0) { if( $p_user_id === null ) { $t_user_id = auth_get_current_user_id(); } else { @@ -363,7 +367,7 @@ $t_project_id = bug_get_field( $p_bug_id, 'project_id' ); $t_user_access_level = user_get_access_level( $t_user_id, $t_project_id ); - $t_all_bugnotes = bugnote_get_all_bugnotes( $p_bug_id ); + $t_all_bugnotes = bugnote_get_all_bugnotes( $p_bug_id, $p_parent_bugnote_id ); $t_private_bugnote_threshold = config_get( 'private_bugnote_threshold' ); $t_private_bugnote_visible = access_compare_level( $t_user_access_level, config_get( 'private_bugnote_threshold' ) ); @@ -407,7 +411,7 @@ * @return array array of bugnotes * @access public */ -function bugnote_get_all_bugnotes( $p_bug_id ) { +function bugnote_get_all_bugnotes( $p_bug_id , $p_parent_bugnote_id = 0) { global $g_cache_bugnotes, $g_cache_bugnote; if( !isset( $g_cache_bugnotes ) ) { @@ -428,12 +432,17 @@ $t_query = "SELECT b.*, t.note FROM $t_bugnote_table b LEFT JOIN $t_bugnote_text_table t ON b.bugnote_text_id = t.id - WHERE b.bug_id=" . db_param() . ' - ORDER BY b.id ASC'; + WHERE b.bug_id=" . db_param(); + + if($p_parent_bugnote_id > -1){ + $t_query .= " AND b.parent_bugnote_id=" . db_param(); + } + + $t_query .= " ORDER BY b.id ASC"; $t_bugnotes = array(); # BUILD bugnotes array - $t_result = db_query_bound( $t_query, array( $p_bug_id ) ); + $t_result = db_query_bound( $t_query, array( $p_bug_id , $p_parent_bugnote_id ) ); while( $row = db_fetch_array( $t_result ) ) { $t_bugnote = new BugnoteData; @@ -454,10 +463,10 @@ $g_cache_bugnote[(int)$t_bugnote->id] = $t_bugnote; } - $g_cache_bugnotes[(int)$p_bug_id] = $t_bugnotes; + $g_cache_bugnotes[(int)$p_bug_id . (int)$p_parent_bugnote_id] = $t_bugnotes; } - return $g_cache_bugnotes[(int)$p_bug_id]; + return $g_cache_bugnotes[(int)$p_bug_id . (int)$p_parent_bugnote_id]; } /** Index: lang/strings_english.txt =================================================================== --- lang/strings_english.txt (revision 211) +++ lang/strings_english.txt (working copy) @@ -96,6 +96,7 @@ $s_bugnote_link_title = 'Direct link to note'; $s_delete_bugnote_button = 'Delete Note'; $s_delete_bugnote_sure_msg = 'Are you sure you wish to delete this note?'; +$s_delete_bugnote_delete_child_bugnotes_first = 'Please delete the Child-Notes first!'; $s_bug_relationships = 'Relationships'; $s_empty_password_sure_msg = 'The user has an empty password. Are you sure that is what you want?'; $s_empty_password_button = 'Use Empty Password'; | ||||
This would be very useful. Issues with many notes can be hard to follow, and some notes are only relevant to some watchers (eg. reporters, developers). Being able to create threads for eg. requirements, design, reviews would be a big improvement. As would be the ability to monitor or un-monitor particular threads. |
|
I think this would be an great feature! We have the same Problem with many notes and parallel activity. Normally we do an "devide an conquere" than and clone the ticket but sometimes it would be great! |
|
I added this feature. Please check the patch and the following sql query. ALTER TABLE |
|
I came here to request the same issue, but found this ticket already exists. So +1 from me I guess... |
|