Index: openacs-4/packages/bug-tracker/www/bug.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/bug-tracker/www/bug.tcl,v diff -u -r1.16 -r1.17 --- openacs-4/packages/bug-tracker/www/bug.tcl 9 Dec 2002 21:24:22 -0000 1.16 +++ openacs-4/packages/bug-tracker/www/bug.tcl 13 Jan 2003 15:26:29 -0000 1.17 @@ -5,223 +5,303 @@ @creation-date 2002-03-20 @cvs-id $Id$ } { - mode:optional bug_number:integer,notnull - edit:optional - comment:optional - reassign:optional - resolve:optional - reopen:optional - cancel:optional - close:optional {user_agent_p:boolean 0} {show_patch_status "open"} filter:array,optional } +##### +# +# Setup +# +##### + set return_url "[ad_conn url]?[export_vars -url { bug_number filter:array }]" -# If the user hit cancel, ignore everything else -if { [exists_and_not_null cancel] } { - ad_returnredirect $return_url - ad_script_abort -} +set project_name [bug_tracker::conn project_name] +set package_id [ad_conn package_id] +set package_key [ad_conn package_key] -ad_require_permission [ad_conn package_id] read +set user_id [ad_conn user_id] -if { ![info exists mode] } { - if { [exists_and_not_null edit] } { - set mode "edit" - } elseif { [exists_and_not_null comment] } { - set mode "comment" - } elseif { [exists_and_not_null reassign] } { - set mode "reassign" - } elseif { [exists_and_not_null resolve] } { - set mode "resolve" - } elseif { [exists_and_not_null reopen] } { - set mode "reopen" - } elseif { [exists_and_not_null close] } { - set mode "close" - } else { - set mode "view" - } +permission::require_permission -object_id $package_id -privilege read + + + +##### +# +# Workflow definition +# +##### + +set workflow_states { open resolved closed } + +set workflow_actions { edit comment reassign resolve reopen close } + +set workflow_roles { submitter assignee } + + +# By state +array set workflow_enabled_actions { + open { comment edit reassign resolve } + resolved { comment edit resolve reopen close } + closed { comment edit reopen } } -switch -- $mode { - edit { - set edit_fields { component_id bug_type summary severity priority found_in_version assignee fix_for_version resolution fixed_in_version } - } - comment { - set edit_fields {} - } - reassign { - set edit_fields { assignee } - } - resolve { - set edit_fields { resolution fixed_in_version } - } - default { - set edit_fields {} - } +# By action +array set workflow_action_privileges { + edit { write } + comment { read } + reassign { write } + resolve { write } + reopen { write } + close { write } } -foreach field $edit_fields { - set field_editable_p($field) 1 + +# By action +array set workflow_action_label { + edit "Edit" + comment "Comment" + reassign "Reassign" + resolve "Resolve" + reopen "Reopen" + close "Close" } +# By action +array set workflow_action_allowed_roles { + edit { assignee submitter } + comment { assignee submitter } + reassign { assignee } + resolve {} + reopen { submitter } + close {} +} +# By action +array set workflow_action_assigned_roles { + edit {} + comment {} + reassign {} + resolve { assignee } + reopen {} + close { submitter } +} -if { ![string equal $mode "view"] } { - ad_maybe_redirect_for_registration -} +# By action +array set workflow_new_status { + {} {} + edit {} + comment {} + reassign {} + resolve resolved + reopen open + close closed +} -set write_p [ad_permission_p [ad_conn package_id] write] +# By action +array set workflow_edit_fields { + {} {} + edit { component_id bug_type summary severity priority found_in_version assignee fix_for_version resolution fixed_in_version } + comment {} + reassign { assignee } + resolve { resolution fixed_in_version } + reopen {} + close {} +} -set project_name [bug_tracker::conn project_name] -set package_id [ad_conn package_id] -set package_key [ad_conn package_key] +# By current state or new state (after action) +array set workflow_hide_fields { + open { resolution fixed_in_version } + resolved {} + closed {} +} -set user_id [ad_conn user_id] - +##### # -# Filter management +# Permissions # +##### -set filter_parsed [bug_tracker::parse_filters filter] +foreach role $workflow_roles { + set user_role($role) 0 +} -if { [string equal $mode view] } { +db_1row permission_info { + select b.bug_id, + b.status, + o.creation_user as submitter_user_id, + b.assignee + from bt_bugs b, + acs_objects o + where b.bug_number = :bug_number + and b.project_id = :package_id + and o.object_id = b.bug_id +} -column_array bug - set human_readable_filter [bug_tracker::conn filter_human_readable] - set where_clauses [bug_tracker::conn filter_where_clauses] - set order_by_clause [bug_tracker::conn filter_order_by_clause] +# If the user has submitted the bug he gets write permission +if { [info exists bug(submitter_user_id)] && ($bug(submitter_user_id) == $user_id) } { + set user_role(submitter) 1 +} - lappend where_clauses "b.project_id = :package_id" +# If the user is assigned to the bug, he gets write permission +if { [info exists bug(assignee)] && ($bug(assignee) == $user_id) } { + set user_role(assignee) 1 +} - set filter_bug_numbers [db_list filter_bug_numbers " - select bug_number - from bt_bugs b join - acs_objects o on (object_id = bug_id) join - bt_priority_codes pc on (pc.priority_id = b.priority) join - bt_severity_codes sc on (sc.severity_id = b.severity) - where [join $where_clauses " and "] - order by $order_by_clause - "] +array set action_permission_p [list {} 1] - set filter_bug_index [lsearch -exact $filter_bug_numbers $bug_number] - - multirow create navlinks url label +foreach loop_action $workflow_actions { + set action_permission_p($loop_action) 0 - if { $filter_bug_index != -1 } { - - if { $filter_bug_index > 0 } { - multirow append navlinks "bug?[export_vars { { bug_number {[lindex $filter_bug_numbers [expr $filter_bug_index -1]]} } filter:array }]" "<" - } else { - multirow append navlinks "" "<" + foreach role [concat $workflow_action_assigned_roles($loop_action) $workflow_action_allowed_roles($loop_action)] { + if { $user_role($role) } { + set action_permission_p($loop_action) 1 + break } - - multirow append navlinks "" "[expr $filter_bug_index+1] of [llength $filter_bug_numbers]" - - if { $filter_bug_index < [expr [llength $filter_bug_numbers]-1] } { - multirow append navlinks "bug?[export_vars { { bug_number {[lindex $filter_bug_numbers [expr $filter_bug_index +1]]} } filter:array }]" ">" - } else { - multirow append navlinks "" ">" + } + + if { !$action_permission_p($loop_action) } { + foreach priv $workflow_action_privileges($loop_action) { + if { [permission::permission_p -object_id $bug(bug_id) -privilege $priv] } { + set action_permission_p($loop_action) 1 + break + } } } } -# Create the form +##### +# +# Action +# +##### -switch -- $mode { - view { - form create bug -has_submit 1 - } - default { - form create bug +set action [form get_action bug] + +# Registration required for all actions +if { ![empty_string_p $action] } { + ad_maybe_redirect_for_registration +} + +# Check permissions +if { !$action_permission_p($action) } { + bug_tracker::security_violation -user_id $user_id -bug_id $bug(bug_id) -action $action +} + +# Buttons +set actions [list] +if { [empty_string_p $action] } { + foreach enabled_action $workflow_enabled_actions(${bug(status)}) { + if { $action_permission_p($enabled_action) } { + lappend actions [list " $workflow_action_label($enabled_action) " $enabled_action] + } } } -element create bug bug_number \ - -datatype integer \ - -widget hidden +##### +# +# Create the form +# +##### -element create bug bug_number_i \ +form create bug -mode display -actions $actions -cancel_url $return_url + +element create bug bug_number_display \ -datatype integer \ -widget inform \ + -mode display \ -label "Bug #" element create bug component_id \ -datatype integer \ - -widget [ad_decode [info exists field_editable_p(component_id)] 1 select inform] \ + -widget select \ + -mode display \ -label "Component" \ -options [bug_tracker::components_get_options] element create bug bug_type \ -datatype text \ - -widget [ad_decode [info exists field_editable_p(bug_type)] 1 select inform] \ + -widget select \ + -mode display \ -label "Type of bug" \ -options [bug_tracker::bug_type_get_options] \ -optional element create bug summary \ -datatype text \ - -widget [ad_decode [info exists field_editable_p(summary)] 1 text inform] \ + -widget text \ + -mode display \ -label "Summary" \ - -html { size 50 } + -html { size 50 } \ + -before_html "" \ + -after_html "" element create bug submitter \ -datatype text \ -widget inform \ + -mode display \ -label "Submitted by" element create bug status \ - -widget [ad_decode [info exists field_editable_p(status)] 1 select inform] \ + -widget select \ + -mode display \ -datatype text \ -options [bug_tracker::status_get_options] \ - -label "Status" + -label "Status" \ + -before_html "" \ + -after_html "" element create bug resolution \ - -widget [ad_decode [info exists field_editable_p(resolution)] 1 select inform] \ + -widget select \ + -mode display \ -datatype text \ -label "Resolution" \ - -options [ad_decode $mode resolve [bug_tracker::resolution_get_options] [concat {{"" ""}} [bug_tracker::resolution_get_options]]] \ + -options [ad_decode $action resolve [bug_tracker::resolution_get_options] [concat {{"" ""}} [bug_tracker::resolution_get_options]]] \ -optional element create bug severity \ -datatype integer \ - -widget [ad_decode [info exists field_editable_p(severity)] 1 select inform] \ + -widget select \ + -mode display \ -label "Severity" \ -options [bug_tracker::severity_codes_get_options] \ -optional element create bug priority \ -datatype integer \ - -widget [ad_decode [info exists field_editable_p(priority)] 1 select inform] \ + -widget select \ + -mode display \ -label "Priority" \ -options [bug_tracker::priority_codes_get_options] \ -optional element create bug found_in_version \ -datatype text \ - -widget [ad_decode [info exists field_editable_p(found_in_version)] 1 select inform] \ + -widget select \ + -mode display \ -label "Found in Version" \ -options [bug_tracker::version_get_options -include_unknown] \ -optional element create bug patches \ -datatype text \ -widget inform \ - -label [ad_decode $show_patch_status "open" "Open Patches (show all)" "all" "All Patches (show only open)" "Patches"] + -mode display \ + -label [ad_decode $show_patch_status "open" "Open Patches (show all)" "all" "All Patches (show only open)" "Patches"] -if { $user_agent_p } { - element create bug user_agent \ - -datatype text \ - -widget inform \ - -label "User Agent" -} +element create bug user_agent \ + -datatype text \ + -widget inform \ + -mode display \ + -label "User Agent" element create bug assignee \ - -widget [ad_decode [info exists field_editable_p(assignee)] 1 search inform] \ + -widget search \ + -mode display \ -datatype search \ -result_datatype integer \ -label {Assigned to} \ @@ -232,392 +312,224 @@ from cc_users u where upper(coalesce(u.first_names || ' ', '') || coalesce(u.last_name || ' ', '') || u.email || ' ' || coalesce(u.screen_name, '')) like upper('%'||:value||'%') order by name -} +} element create bug fix_for_version \ -datatype text \ - -widget [ad_decode [info exists field_editable_p(fix_for_version)] 1 select inform] \ + -widget select \ + -mode display \ -label "Fix for Version" \ -options [bug_tracker::version_get_options -include_undecided] \ -optional element create bug fixed_in_version \ -datatype text \ - -widget [ad_decode [info exists field_editable_p(fixed_in_version)] 1 select inform] \ + -widget select \ + -mode display \ -label "Fixed in Version" \ -options [bug_tracker::version_get_options -include_undecided] \ -optional -switch -- $mode { - edit - comment - reassign - resolve - reopen - close { - element create bug description \ - -datatype text \ - -widget comment \ - -label "Description" \ - -html { cols 60 rows 13 } \ - -optional - - element create bug desc_format \ - -datatype text \ - -widget select \ - -label "Description format" \ - -options { { "Plain" plain } { "HTML" html } { "Preformatted" pre } } +element create bug description \ + -datatype text \ + -widget comment \ + -history [bug_tracker::bug::get_activity_html -bug_id $bug(bug_id)] \ + -label "Description" \ + -html { cols 60 rows 13 } \ + -format_element desc_format \ + -format_options { { "Plain" plain } { "HTML" html } { "Preformatted" pre } } \ + -optional - } - default { - element create bug description \ - -datatype text \ - -widget inform \ - -label "Description" - } -} +# Hidden elements - element create bug return_url \ -datatype text \ -widget hidden \ -value $return_url -element create bug mode \ - -datatype text \ - -widget hidden \ - -value $mode +element create bug bug_number \ + -datatype integer \ + -widget hidden +# Export filters foreach name [array names filter] { element create bug filter.$name -datatype text -widget hidden -value $filter($name) } -# If nothing else ... -set page_title "Bug #$bug_number" +# Set editable fields +foreach field $workflow_edit_fields($action) { + element set_properties bug $field -mode edit +} -set show_user_agent_url "bug?[export_vars { bug_number { user_agent_p 1 }}]" -set hide_user_agent_url "bug?[export_vars { bug_number }]" -if { ![form is_valid bug] } { - db_1row bug { - select b.bug_id, - b.bug_number, - b.summary, - o.creation_user as submitter_user_id, - submitter.first_names as submitter_first_names, - submitter.last_name as submitter_last_name, - submitter.email as submitter_email, - b.component_id, - c.component_name, - o.creation_date, - to_char(o.creation_date, 'fmMM/DDfm/YYYY') as creation_date_pretty, - b.severity, - sc.sort_order || ' - ' || sc.severity_name as severity_pretty, - b.priority, - pc.sort_order || ' - ' || pc.priority_name as priority_pretty, - b.status, - b.resolution, - b.bug_type, - b.user_agent, - b.original_estimate_minutes, - b.latest_estimate_minutes, - b.elapsed_time_minutes, - b.found_in_version, - coalesce((select version_name - from bt_versions found_in_v - where found_in_v.version_id = b.found_in_version), 'Unknown') as found_in_version_name, - b.fix_for_version, - coalesce((select version_name - from bt_versions fix_for_v - where fix_for_v.version_id = b.fix_for_version), 'Undecided') as fix_for_version_name, - b.fixed_in_version, - coalesce((select version_name - from bt_versions fixed_in_v - where fixed_in_v.version_id = b.fixed_in_version), 'Unknown') as fixed_in_version_name, - b.assignee, - asgnu.first_names as assignee_first_names, - asgnu.last_name as assignee_last_name, - asgnu.email as assignee_email, - to_char(now(), 'fmMM/DDfm/YYYY') as now_pretty - from bt_bugs b left outer join - cc_users asgnu on (asgnu.user_id = b.assignee), - acs_objects o, - bt_components c, - bt_priority_codes pc, - bt_severity_codes sc, - cc_users submitter - where b.bug_number = :bug_number - and b.project_id = :package_id - and o.object_id = b.bug_id - and c.component_id = b.component_id - and pc.priority_id = b.priority - and sc.severity_id = b.severity - and submitter.user_id = o.creation_user - } -column_array bug - - switch -- $mode { - resolve { - set bug(status) "resolved" - } - reopen { - set bug(status) "open" - } - } - set pretty(bug_number) "#$bug(bug_number)" - set pretty(component_id) $bug(component_name) - set pretty(bug_type) [bug_tracker::bug_type_pretty $bug(bug_type)] - set pretty(summary) "$bug(summary)" - set pretty(submitter) "[acs_community_member_link -user_id $bug(submitter_user_id) \ - -label "$bug(submitter_first_names) $bug(submitter_last_name)" \ - ] ($bug(submitter_email))" - set pretty(status) [bug_tracker::status_pretty $bug(status)] - set pretty(resolution) [bug_tracker::resolution_pretty $bug(resolution)] - set pretty(severity) $bug(severity_pretty) - set pretty(priority) $bug(priority_pretty) - set pretty(found_in_version) $bug(found_in_version_name) - set pretty(patches) "[bug_tracker::get_patch_links -bug_id $bug(bug_id) -show_patch_status $show_patch_status]   \[ Upload a patch \]" - set pretty(user_agent) $bug(user_agent) - set pretty(fix_for_version) $bug(fix_for_version_name) - set pretty(fixed_in_version) $bug(fixed_in_version_name) - set pretty(assignee) [ad_decode $bug(assignee) "" "Unassigned" " - [acs_community_member_link -user_id $bug(assignee) \ - -label "$bug(assignee_first_names) $bug(assignee_last_name)"] - ($bug(assignee_email))"] -} -if { [form is_request bug] } { - element set_properties bug bug_number -value $bug(bug_number) +##### +# +# Valid form submission: Store in DB and get out of here +# +##### - # Description/Actions/History +if { [form is_valid bug] } { - set bug_id $bug(bug_id) + # Get values from form + array set row [list] - set action_html "" - - db_foreach actions { - select ba.action_id, - ba.action, - ba.resolution, - ba.actor as actor_user_id, - actor.first_names as actor_first_names, - actor.last_name as actor_last_name, - actor.email as actor_email, - ba.action_date, - to_char(ba.action_date, 'fmMM/DDfm/YYYY') as action_date_pretty, - ba.comment, - ba.comment_format - from bt_bug_actions ba, - cc_users actor - where ba.bug_id = :bug_id - and actor.user_id = ba.actor - order by action_date - } { - append action_html "$action_date_pretty [bug_tracker::bug_action_pretty $action $resolution] by $actor_first_names $actor_last_name -
[bug_tracker::bug_convert_comment_to_html -comment $comment -format $comment_format]
" + foreach column $workflow_edit_fields($action) { + set row($column) [element get_value bug $column] } - if { [string equal $mode "view"] } { - element set_properties bug description -value $action_html - } else { - element set_properties bug description \ - -history $action_html \ - -header "$bug(now_pretty) [bug_tracker::bug_action_pretty $mode] by [bug_tracker::conn user_first_names] [bug_tracker::conn user_last_name]" \ - -value "" + # Set new status + if { ![empty_string_p $workflow_new_status($action)] } { + set row(status) $workflow_new_status($action) } - set page_title "Bug #$bug_number: $bug(summary)" + bug_tracker::bug::edit \ + -bug_id $bug(bug_id) \ + -action $action \ + -description [element get_value bug description] \ + -desc_format [ns_queryget desc_format] \ + -array row - # If the user has submitted the bug he gets full write access on the bug - set write_p [expr $write_p || ($bug(submitter_user_id) == [ad_conn user_id])] - if { !$write_p && [info exists bug(assignee)] && $bug(assignee) == [ad_conn user_id] } { - set write_p 1 - } + ad_returnredirect $return_url + ad_script_abort +} - if { [string equal $mode "view"] } { - set button_form_export_vars [export_vars -form { bug_number filter:array }] - multirow create button name label - multirow append button "comment" "Comment" - if { $write_p } { - multirow append button "edit" "Edit" - switch -- $bug(status) { - open { - multirow append button "reassign" "Reassign" - multirow append button "resolve" "Resolve" - } - resolved { - multirow append button "resolve" "Resolve" - multirow append button "reopen" "Reopen" - multirow append button "close" "Close" - } - closed { - multirow append button "reopen" "Reopen" - } - } - } +##### +# +# Display form +# +##### + +# Get bug info from DB, hide form elements, set values +if { ![form is_valid bug] } { + + # Get the bug data + bug_tracker::bug::get -bug_id $bug(bug_id) -array bug + + # Maybe bump to new state + if { ![empty_string_p $workflow_new_status($action)] } { + set bug(status) $workflow_new_status($action) } - if { ![string equal $mode "view"] && ![string equal $mode "comment"] && !$write_p } { - ns_log notice "[ad_conn user_id] doesn't have write on object $bug(bug_id)" - ad_return_forbidden "Security Violation" "
- You don't have permission to edit this bug. -
- This incident has been logged. -
" - ad_script_abort + # Patches + set bug(patches_display) "[bug_tracker::get_patch_links -bug_id $bug(bug_id) -show_patch_status $show_patch_status]   \[ Upload a patch \]" + + # Hide elements that should be hidden depending on the bug status + foreach element $workflow_hide_fields(${bug(status)}) { + element set_properties bug $element -widget hidden } -} -if { ![form is_valid bug] } { - # set the values of all the inform widgets + # Optionally hide user agent + if { !$user_agent_p } { + element set_properties bug user_agent -widget hidden + } - element set_properties bug bug_number_i -value $pretty(bug_number) - + # Set regular element values foreach element { - component_id bug_type summary submitter status resolution severity - priority found_in_version patches user_agent fix_for_version fixed_in_version assignee + bug_number component_id bug_type summary status resolution severity assignee + priority found_in_version user_agent fix_for_version fixed_in_version + bug_number_display } { # check that the element exists if { [info exists bug:$element] } { - if { [info exists field_editable_p($element)] } { - if { [form is_request bug] } { - element set_value bug $element $bug($element) - } - } else { - element set_value bug $element $pretty($element) + if { [form is_request bug] || [string equal [element get_property bug $element mode] "display"] } { + element set_value bug $element $bug($element) } } - } - - if { [string equal $bug(status) "open"] && ![string equal $mode "resolve"] || [string equal $mode "reopen"] } { - element set_properties bug resolution -widget hidden - element set_properties bug fixed_in_version -widget hidden } - -} - - - -# Notifications for a project. Provide a link for logged in users in view mode -if { [string equal $mode "view"] } { - set notification_link [bug_tracker::get_notification_link \ - -type bug_tracker_project_notif \ - -object_id $bug(bug_id) \ - -url $return_url \ - -pretty_name "bug"] -} else { - set notification_link "" -} - -if { [info exists filter] } { - if { [array names filter] == [list "actionby"] && $filter(actionby) == [ad_conn user_id] } { - set context_bar [bug_tracker::context_bar [list ".?[export_vars { filter:array }]" "My bugs"] $page_title] - } else { - set context_bar [bug_tracker::context_bar [list ".?[export_vars { filter:array }]" "Filtered bug list"] $page_title] - } -} else { - set context_bar [bug_tracker::context_bar $page_title] -} - -if { [form is_valid bug] } { - - # Find out whether the user has permission to modify - - if { !$write_p } { - # No write permission, is this the submitter? - db_1row submitter { - select o.creation_user as submitter_user_id, - b.bug_id, - b.assignee - from bt_bugs b, - acs_objects o - where o.object_id = b.bug_id - and b.bug_number = :bug_number - and b.project_id = :package_id - } -column_array bug - - # If the user has submitted the bug he gets full write access on the bug - if { [info exists bug(submitter_user_id)] && ($bug(submitter_user_id) == [ad_conn user_id]) } { - set write_p 1 + # Set values for elements with separate display value + foreach element { + assignee submitter patches + } { + # check that the element exists + if { [info exists bug:$element] } { + element set_properties bug $element -display_value $bug(${element}_display) } - - if { [info exists bug(assignee)] && ($bug(assignee) == [ad_conn user_id]) } { - set write_p 1 - } } - if { !$write_p && ![string equal $mode "comment"] } { - ns_log notice "$bug(submitter_user_id) doesn't have write on object $bug(bug_id)" - ad_return_forbidden \ - "Security Violation" \ - "
- You don't have permission to edit this bug. -
- This incident has been logged. -
" - ad_script_abort - } + # Set values for description field + element set_properties bug description \ + -header "$bug(now_pretty) [bug_tracker::bug_action_pretty $action] by [bug_tracker::conn user_first_names] [bug_tracker::conn user_last_name]" - set update_exprs [list] + # Set page title + set page_title "Bug #$bug_number: $bug(summary)" - foreach column $edit_fields { - set $column [element get_value bug $column] - lappend update_exprs "$column = :$column" - } - - switch -- $mode { - resolve { - set status "resolved" - lappend update_exprs "status = :status" + # Context bar + if { [info exists filter] } { + if { [array names filter] == [list "actionby"] && $filter(actionby) == $user_id } { + set context_bar [bug_tracker::context_bar [list ".?[export_vars { filter:array }]" "My bugs"] $page_title] + } else { + set context_bar [bug_tracker::context_bar [list ".?[export_vars { filter:array }]" "Filtered bug list"] $page_title] } - reopen { - set status "open" - lappend update_exprs "status = :status" - } - close { - set status "closed" - lappend update_exprs "status = :status" - } + } else { + set context_bar [bug_tracker::context_bar $page_title] } - - if { ![info exists resolution] || ![string equal $mode "resolve"] } { - set resolution {} + + # User agent + set show_user_agent_url "bug?[export_vars { bug_number { user_agent_p 1 }}]" + set hide_user_agent_url "bug?[export_vars { bug_number }]" + + # Login + set login_url "/register/?[export_vars { return_url }]" + + # Single-bug notifications + if { [empty_string_p $action] } { + set notification_link [bug_tracker::get_notification_link \ + -type bug_tracker_bug_notif \ + -object_id $bug(bug_id) \ + -url $return_url \ + -pretty_name "bug"] } - db_transaction { - set bug_id [bug_tracker::get_bug_id -bug_number $bug_number -project_id $package_id] - if { [llength $update_exprs] > 0 } { - db_dml update_bug "update bt_bugs \n set [join $update_exprs ",\n "] \n where bug_id = :bug_id" + # Filter management + set filter_parsed [bug_tracker::parse_filters filter] + + if { [empty_string_p $action] } { + + set human_readable_filter [bug_tracker::conn filter_human_readable] + set where_clauses [bug_tracker::conn filter_where_clauses] + set order_by_clause [bug_tracker::conn filter_order_by_clause] + + lappend where_clauses "b.project_id = :package_id" + + set filter_bug_numbers [db_list filter_bug_numbers " + select bug_number + from bt_bugs b join + acs_objects o on (object_id = bug_id) join + bt_priority_codes pc on (pc.priority_id = b.priority) join + bt_severity_codes sc on (sc.severity_id = b.severity) + where [join $where_clauses " and "] + order by $order_by_clause + "] + + set filter_bug_index [lsearch -exact $filter_bug_numbers $bug_number] + + multirow create navlinks url label + + if { $filter_bug_index != -1 } { + + if { $filter_bug_index > 0 } { + multirow append navlinks "bug?[export_vars { { bug_number {[lindex $filter_bug_numbers [expr $filter_bug_index -1]]} } filter:array }]" "<" + } else { + multirow append navlinks "" "<" + } + + multirow append navlinks "" "[expr $filter_bug_index+1] of [llength $filter_bug_numbers]" + + if { $filter_bug_index < [expr [llength $filter_bug_numbers]-1] } { + multirow append navlinks "bug?[export_vars { { bug_number {[lindex $filter_bug_numbers [expr $filter_bug_index +1]]} } filter:array }]" ">" + } else { + multirow append navlinks "" ">" + } } + } - set action_id [db_nextval "acs_object_id_seq"] - set user_id [ad_conn user_id] - - foreach column { description desc_format } { - set $column [element get_value bug $column] - } - - db_dml bug_action { - insert into bt_bug_actions - (action_id, bug_id, action, resolution, actor, comment, comment_format) - values - (:action_id, :bug_id, :mode, :resolution, :user_id, :description, :desc_format) - } - - # Setup any assignee for alerts on the bug - if { [info exists assignee] && ![empty_string_p $assignee] } { - bug_tracker::add_instant_alert -bug_id $bug_id -user_id $assignee - } - } - - bug_tracker::bug_notify -bug_id $bug_id \ - -action $mode \ - -comment $description \ - -comment_format $desc_format \ - -resolution $resolution - - ad_returnredirect $return_url - ad_script_abort } ad_return_template