Commit 355cb972 authored by myk%mozilla.org's avatar myk%mozilla.org

Fix for bug 126792: Templatizes showdependencytree.cgi.

Patch by Myk Melez <myk@mozilla.org>. r=afranke,gerv
parent 65733e36
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
# Contributor(s): Terry Weissman <terry@mozilla.org> # Contributor(s): Terry Weissman <terry@mozilla.org>
# Andreas Franke <afranke@mathweb.org> # Andreas Franke <afranke@mathweb.org>
# Christian Reis <kiko@async.com.br> # Christian Reis <kiko@async.com.br>
# Myk Melez <myk@mozilla.org>
use diagnostics; use diagnostics;
use strict; use strict;
...@@ -28,6 +29,9 @@ use strict; ...@@ -28,6 +29,9 @@ use strict;
use lib qw(.); use lib qw(.);
require "CGI.pl"; require "CGI.pl";
# Use global template variables.
use vars qw($template $vars);
use vars %::FORM; use vars %::FORM;
ConnectToDatabase(); ConnectToDatabase();
...@@ -38,384 +42,152 @@ quietly_check_login(); ...@@ -38,384 +42,152 @@ quietly_check_login();
$::userid = $::userid; $::userid = $::userid;
$::usergroupset = $::usergroupset; $::usergroupset = $::usergroupset;
###################################################################### ################################################################################
# Begin Data/Security Validation # Data/Security Validation #
###################################################################### ################################################################################
# Make sure the bug ID is a positive integer representing an existing # Make sure the bug ID is a positive integer representing an existing
# bug that the user is authorized to access # bug that the user is authorized to access.
ValidateBugID($::FORM{'id'}); ValidateBugID($::FORM{'id'});
my $id = $::FORM{'id'}; my $id = $::FORM{'id'};
my $hide_resolved = $::FORM{'hide_resolved'} || 0;
my $maxdepth = $::FORM{'maxdepth'} || 0;
if ($maxdepth !~ /^\d+$/) { $maxdepth = 0 };
if ($hide_resolved !~ /^\d+$/ || $hide_resolved != 1) { $hide_resolved = 0 };
###################################################################### my $hide_resolved = $::FORM{'hide_resolved'} ? 1 : 0;
# End Data/Security Validation
######################################################################
# my $maxdepth = $::FORM{'maxdepth'} || 0;
# Globals if ($maxdepth !~ /^\d+$/) { $maxdepth = 0 };
# A hash to count visited bugs, and also to avoid processing repeated bugs
my %seen;
# A hash to keep track of the bugs we print for the 'as buglist' links. ################################################################################
my %printed; # Main Section #
################################################################################
# HTML output generated in the parse of the dependency tree. This is a # The column/value to select as the target milestone for bugs,
# global only to avoid excessive complication in the recursion invocation # either the target_milestone column or the empty string value
my $html; # (for installations that don't use target milestones). Makes
# it easier to query the database for bugs because we don't
# have to embed a conditional statement into each query.
my $milestone_column = Param('usetargetmilestone') ? "target_milestone" : "''";
# Saves the largest of the two actual depths of the trees # The greatest depth to which either tree goes.
my $realdepth = 0; my $realdepth = 0;
# The scriptname for use as FORM ACTION. # Generate the tree of bugs that this bug depends on and a list of IDs
my $scriptname = $::ENV{'SCRIPT_NAME'}; # showdependencytree.cgi # appearing in the tree.
my $dependson_tree = { $id => GetBug($id) };
# my $dependson_ids = {};
# Functions GenerateTree($id, "dependson", 1, $dependson_tree, $dependson_ids);
$vars->{'dependson_tree'} = $dependson_tree;
# DumpKids recurses through the bug hierarchy starting at bug i, and $vars->{'dependson_ids'} = [keys(%$dependson_ids)];
# appends the bug information found to the html global variable. The
# parameters are not straightforward, so look at the examples. # Generate the tree of bugs that this bug blocks and a list of IDs
# # appearing in the tree.
# DumpKids(i, target [, depth]) my $blocked_tree = { $id => GetBug($id) };
# my $blocked_ids = {};
# Params GenerateTree($id, "blocked", 1, $blocked_tree, $blocked_ids);
# i: The bug id to analyze $vars->{'blocked_tree'} = $blocked_tree;
# target: The type we are looking for; either "blocked" or "dependson" $vars->{'blocked_ids'} = [keys(%$blocked_ids)];
# Optional
# depth: The current dependency depth we are analyzing, used during $vars->{'realdepth'} = $realdepth;
# recursion
# Globals Modified $vars->{'bugid'} = $id;
# html: Bug descriptions are appended here $vars->{'maxdepth'} = $maxdepth;
# realdepth: We set the maximum depth of recursion reached $vars->{'hide_resolved'} = $hide_resolved;
# seen: We store the bugs analyzed so far $vars->{'canedit'} = UserInGroup("editbugs");
# printed: We store those bugs we actually print, for the "buglist" link
# Globals Referenced print "Content-Type: text/html\n\n";
# maxdepth $template->process("show/dependency-tree.html.tmpl", $vars)
# hide_resolved || DisplayError("Template process failed: " . $template->error())
# && exit;
# Examples:
# DumpKids(163, "blocked"); ################################################################################
# will look for bugs that depend on bug 163 # Recursive Tree Generation Function #
# DumpKids(163, "dependson"); ################################################################################
# will look for bugs on which bug 163 depends
sub GenerateTree {
sub DumpKids { # Generates a dependency tree for a given bug. Calls itself recursively
my ($i, $target, $depth) = (@_); # to generate sub-trees for the bug's dependencies.
my $bgcolor = "#d9d9d9";
my $fgcolor = "#000000"; my ($bug_id, $relationship, $depth, $bugs, $ids) = @_;
my $me;
if (! defined $depth) { $depth = 1; } # Query the database for bugs with the given dependency relationship.
my @dependencies = GetDependencies($bug_id, $relationship);
if ($target eq "blocked") {
$me = "dependson"; # Don't do anything if this bug doesn't have any dependencies.
} else { return unless scalar(@dependencies);
$me = "blocked";
} # Record this depth in the global $realdepth variable if it's farther
SendSQL("select $target from dependencies where $me=$i order by $target"); # than we've gone before.
my @list; $realdepth = max($realdepth, $depth);
while (MoreSQLData()) {
push(@list, FetchOneColumn()); foreach my $dep_id (@dependencies) {
} # Get this dependency's record from the database and generate
if (@list) { # its sub-tree if we haven't already done so (which happens
my $list_started = 0; # when bugs appear in dependency trees multiple times).
foreach my $kid (@list) { if (!$bugs->{$dep_id}) {
my ($bugid, $stat, $milestone) = ("", "", ""); $bugs->{$dep_id} = GetBug($dep_id);
my ($userid, $short_desc) = ("", ""); GenerateTree($dep_id, $relationship, $depth+1, $bugs, $ids);
if (Param('usetargetmilestone')) { }
SendSQL(SelectVisible("select bugs.bug_id, bug_status, target_milestone, assigned_to, short_desc from bugs where bugs.bug_id = $kid", $::userid, $::usergroupset));
($bugid, $stat, $milestone, $userid, $short_desc) = (FetchSQLData());
} else {
SendSQL(SelectVisible("select bugs.bug_id, bug_status, assigned_to, short_desc from bugs where bugs.bug_id = $kid", $::userid, $::usergroupset));
($bugid, $stat, $userid, $short_desc) = (FetchSQLData());
}
if (! defined $bugid) { next; }
my $opened = IsOpenedState($stat);
if ($hide_resolved && ! $opened) { next; }
# If we specify a maximum depth, we hide the output when
# that depth has occured, but continue recursing so we know
# the real maximum depth of the tree.
if (! $maxdepth || $depth <= $maxdepth) {
if (! $list_started) { $html .= "<ul>"; $list_started = 1 }
$html .= "<li>";
if (! $opened) {
$html .= qq|<strike><span style="color: $fgcolor; background-color: $bgcolor;">
|;
}
if (exists $printed{$kid}) {
$short_desc = "&lt;<em>This bug appears elsewhere in this tree</em>&gt;";
}
else {
$short_desc = html_quote($short_desc);
}
SendSQL("select login_name from profiles where userid = $userid");
my ($owner) = (FetchSQLData());
if ((Param('usetargetmilestone')) && ($milestone)) {
$html .= qq|
<a href="show_bug.cgi?id=$kid">$kid [$milestone, $owner]
- $short_desc.</a>
|;
} else {
$html .= qq|
<a href="show_bug.cgi?id=$kid">$kid [$owner] -
$short_desc.</a>\n|;
}
if (! $opened) { $html .= "</span></strike>"; }
$printed{$kid} = 1;
} # End hideable output
# Store the maximum depth so far # Add this dependency to the list of this bug's dependencies
$realdepth = $realdepth < $depth ? $depth : $realdepth; # if it exists, if we haven't exceeded the maximum depth the user
if (!(exists $seen{$kid})) { # wants the tree to go, and if the dependency isn't resolved
$seen{$kid} = 1; # (if we're ignoring resolved dependencies).
DumpKids($kid, $target, $depth + 1); if ($bugs->{$dep_id}->{'exists'}
} && (!$maxdepth || $depth <= $maxdepth)
&& ($bugs->{$dep_id}->{'open'} || !$hide_resolved))
{
push (@{$bugs->{$bug_id}->{'dependencies'}}, $dep_id);
$ids->{$dep_id} = 1;
} }
if ($list_started) { $html .= "</ul>"; }
} }
} }
# makeTreeHTML calls DumpKids and generates the HTML output for a sub GetBug {
# dependency/blocker section. # Retrieves the necessary information about a bug, stores it in the bug cache,
# # and returns it to the calling code.
# makeTreeHTML(i, linked_id, target); my ($id) = @_;
#
# Params
# i: Bug id
# linked_id: Linkified bug_id used to linkify the bug
# target: The type we are looking for; either "blocked" or "dependson"
# Globals modified
# html [Also modified in our call to DumpKids]
# Globals referenced
# seen [Also modified by DumpKids]
# maxdepth
# realdepth
#
# Example:
# $depend_html = makeTreeHTML(83058, <A HREF="...">83058</A>, "dependson");
# Will generate HTML for bugs that depend on bug 83058
sub makeTreeHTML {
my ($i, $linked_id, $target) = @_;
# Clean up globals for this run
$html = "";
%seen = ();
%printed = ();
DumpKids($i, $target);
my $tmphtml = $html;
# Output correct heading
$html = "<h3>Bugs that bug $linked_id ".($target eq "blocked" ?
"blocks" : "depends on");
# If there are some bugs in this tree, add a link to view them
# as a bug list, and add another link to edit them on the "change
# several bugs" page if there is more than one and the user has
# "editbugs" privileges.
if ((scalar keys %printed) > 0) {
my $link = "buglist.cgi?bug_id=" . join(',', keys %printed);
$html .= qq~ (<a href="$link">view as bug list</a>~;
if (UserInGroup("editbugs") && (scalar keys %printed) > 1) {
$html .= qq~ | <a href="$link&tweak=1">change several</a>~;
}
$html .= ')';
}
# Provide feedback for omitted bugs SendSQL(SelectVisible("SELECT 1,
if ($maxdepth || $hide_resolved) { bug_status,
$html .= " <small><b>(Only "; short_desc,
if ($hide_resolved) { $html .= "open "; } $milestone_column,
$html .= "bugs "; assignee.userid,
if ($maxdepth) { $html .= "whose depth is less than $maxdepth "; } assignee.login_name
$html .= "will be shown)</b></small>"; FROM bugs, profiles AS assignee
} WHERE bugs.bug_id = $id
AND bugs.assigned_to = assignee.userid",
$html .= "</h3>"; $::userid,
$html .= $tmphtml; $::usergroupset));
# If no bugs were found, say so my $bug = {};
if ((scalar keys %printed) == 0) {
$html .= "&nbsp;&nbsp;&nbsp;&nbsp;None<p>\n"; ($bug->{'exists'},
} $bug->{'status'},
$bug->{'summary'},
return $html; $bug->{'milestone'},
$bug->{'assignee_id'},
$bug->{'assignee_email'}) = FetchSQLData();
$bug->{'open'} = IsOpenedState($bug->{'status'});
$bug->{'dependencies'} = ();
return $bug;
} }
# Draw the actual form controls that make up the hide/show resolved and sub GetDependencies {
# depth control toolbar. # Returns a list of dependencies for a given bug.
#
# drawDepForm()
#
# Params
# none
# Globals modified
# none
# Globals referenced
# hide_resolved
# maxdepth
# realdepth
sub drawDepForm {
my $bgcolor = "#d0d0d0";
my ($hide_msg, $hide_input);
# Set the text and action for the hide resolved button.
if ($hide_resolved) {
$hide_input = '<input type="hidden" name="hide_resolved" value="0">';
$hide_msg = "Show Resolved";
} else {
$hide_input = '<input type="hidden" name="hide_resolved" value="1">';
$hide_msg = "Hide Resolved";
}
print qq|
<table cellpadding="3" border="0" cellspacing="0">
<tr>
<!-- Hide/show resolved button
Swaps text depending on the state of hide_resolved -->
<td bgcolor="$bgcolor" align="center">
<form method="get" action="$scriptname"
style="display: inline; margin: 0px;">
<input name="id" type="hidden" value="$id">
| . ( $maxdepth ?
qq|<input name="maxdepth" type="hidden" value="$maxdepth">|
: "" ) . qq|
$hide_input
<input type="submit" value="$hide_msg">
</form>
</td>
<td bgcolor="$bgcolor">
<!-- depth section -->
Max Depth:
</td> my ($id, $relationship) = @_;
<td bgcolor="$bgcolor">
</td>
<td bgcolor="$bgcolor">
<form method="get" action="$scriptname"
style="display: inline; margin: 0px;">
<!-- set to one form --> my $bug_type = ($relationship eq "blocked") ? "dependson" : "blocked";
<input type="submit" value="&nbsp;1&nbsp;" |
. ( $realdepth < 2 || $maxdepth == 1 ? "disabled" : "" ) . qq|>
<input name="id" type="hidden" value="$id">
<input name="maxdepth" type="hidden" value="1">
<input name="hide_resolved" type="hidden" value="$hide_resolved">
</form>
</td>
<td bgcolor="$bgcolor">
<form method="get" action="$scriptname"
style="display: inline; margin: 0px;">
<!-- Minus one form
Allow subtracting only when realdepth and maxdepth > 1 -->
<input name="id" type="hidden" value="$id">
<input name="maxdepth" type="hidden" value="|
. ( $maxdepth == 1 ? 1 : ( $maxdepth ?
$maxdepth-1 : $realdepth-1 ) ) . qq|">
<input name="hide_resolved" type="hidden" value="$hide_resolved">
<input type="submit" value="&nbsp;&lt;&nbsp;" |
. ( $realdepth < 2 || ( $maxdepth && $maxdepth < 2 ) ?
"disabled" : "" ) . qq|>
</form>
</td>
<td bgcolor="$bgcolor">
<form method="get" action="$scriptname"
style="display: inline; margin: 0px;">
<!-- Limit entry form: the button can not do anything when total depth
is less than two, so disable it -->
<input name="maxdepth" size="4" maxlength="4" value="|
. ( $maxdepth > 0 ? $maxdepth : "" ) . qq|">
<input name="id" type="hidden" value="$id">
<input name="hide_resolved" type="hidden"
value="$hide_resolved">
<noscript>
<input type="submit" value="Change" |
. ( $realdepth < 2 ? "disabled" : "" ) . qq|>
</noscript>
</form>
</td>
<td bgcolor="$bgcolor">
<form method="get" action="$scriptname"
style="display: inline; margin: 0px;">
<!-- plus one form SendSQL(" SELECT $relationship
Disable button if total depth < 2, or if depth set to unlimited --> FROM dependencies
<input name="id" type="hidden" value="$id"> WHERE $bug_type = $id
| . ( $maxdepth ? qq| ORDER BY $relationship");
<input name="maxdepth" type="hidden" value="|.($maxdepth+1).qq|">| : "" )
. qq|
<input name="hide_resolved" type="hidden" value="$hide_resolved">
<input type="submit" value="&nbsp;&gt;&nbsp;" |
. ( $realdepth < 2 || ! $maxdepth || $maxdepth >= $realdepth ?
"disabled" : "" ) . qq|>
</form>
</td>
<td bgcolor="$bgcolor">
<form method="get" action="$scriptname"
style="display: inline; margin: 0px;">
<!-- Unlimited button --> my @dependencies = ();
<input name="id" type="hidden" value="$id"> push(@dependencies, FetchOneColumn()) while MoreSQLData();
<input name="hide_resolved" type="hidden" value="$hide_resolved">
<input type="submit" value="&nbsp;Unlimited&nbsp;"> return @dependencies;
</form>
</td>
</tr></table>
|;
} }
######################################################################
# Main Section
######################################################################
my $linked_id = qq|<a href="show_bug.cgi?id=$id">$id</a>|;
# Start the tree walk and save results. The tree walk generates HTML but
# needs to be called before the page output starts so we have the
# realdepth, which is necessary for generating the control toolbar.
# Get bugs we depend on
my $depend_html = makeTreeHTML($id, $linked_id, "dependson");
my $tmpdepth = $realdepth;
$realdepth = 0;
# Get bugs we block
my $block_html = makeTreeHTML($id, $linked_id, "blocked");
# Select maximum depth found for use in the toolbar
$realdepth = $realdepth < $tmpdepth ? $tmpdepth : $realdepth;
#
# Actual page output happens here
print "Content-type: text/html\n\n";
PutHeader("Dependency tree for Bug $id", "Dependency tree for Bug $linked_id");
drawDepForm();
print $depend_html;
print $block_html;
drawDepForm();
PutFooter();
[%# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Tobias Burnus <burnus@net-b.de>
# Ville Skytt <ville.skytta@iki.fi>
# Myk Melez <myk@mozilla.org>
#%]
[% PROCESS global/header
title = "Dependency tree for Bug $bugid"
h1 = "Dependency tree for bug <a href=\"show_bug.cgi?id=$bugid\">$bugid</a>"
style = "strike { background-color: #d9d9d9; color: #000000; }"
%]
[% PROCESS depthControlToolbar %]
[%# Display the tree of bugs that this bug depends on. %]
<h3>Bugs that bug <a href="show_bug.cgi?id=[% bugid %]">[% bugid %]</a> depends on
[% IF dependson_ids.size > 0 %]
(<a href="buglist.cgi?bug_id=[% dependson_ids.join(",") %]">view as bug list</a>
[% IF canedit && dependson_ids.size > 1 %]
| <a href="buglist.cgi?bug_id=[% dependson_ids.join(",") %]&amp;tweak=1">change several</a>
[% END %])
[% IF maxdepth || hide_resolved %]
<small><b>
(Only [% "open" IF hide_resolved %] bugs
[% " whose depth is less than $maxdepth" IF maxdepth %]
will be shown)
</b></small>
[% END %]
</h3>
[% INCLUDE display_tree tree=dependson_tree bug_id=bugid %]
[% ELSE %]
</h3>
<p>None</p>
[% END %]
[%# Display the tree of bugs that this bug blocks. %]
<h3>Bugs that bug <a href="show_bug.cgi?id=[% bugid %]">[% bugid %]</a> blocks
[% IF blocked_ids.size > 0 %]
(<a href="buglist.cgi?bug_id=[% blocked_ids.join(",") %]">view as bug list</a>
[% IF canedit && blocked_ids.size > 1 %]
| <a href="buglist.cgi?bug_id=[% blocked_ids.join(",") %]&amp;tweak=1">change several</a>
[% END %])
[% IF maxdepth || hide_resolved %]
<small><b>
(Only [% "open" IF hide_resolved %] bugs
[% " whose depth is less than $maxdepth" IF maxdepth %]
will be shown)
</b></small>
[% END %]
</h3>
[% INCLUDE display_tree tree=blocked_tree bug_id=bugid %]
[% ELSE %]
</h3>
<p>None</p>
[% END %]
[% PROCESS depthControlToolbar %]
[% PROCESS global/footer %]
[%###########################################################################%]
[%# Block to display a tree #%]
[%###########################################################################%]
[% BLOCK display_tree %]
<ul>
[% FOREACH dep_id = tree.$bug_id.dependencies %]
[% dep = tree.$dep_id %]
<li>
[% "<strike>" IF !dep.open %]
<a href="show_bug.cgi?id=[% dep_id %]">[% dep_id %]
[[% IF dep.milestone %][% dep.milestone FILTER html %], [% END %]
[% dep.assignee_email FILTER html %]] -
[% IF dep.seen %]
<i>&lt;This bug appears elsewhere in this tree&gt;</i></a>
[% ELSE %]
[% dep.summary FILTER html %].</a>
[% END %]
[% "</strike>" IF !dep.open %]
[% INCLUDE display_tree bug_id=dep_id
IF dep.dependencies.size > 0 && !dep.seen %]
</li>
[% dep.seen = 1 %]
[% END %]
</ul>
[% END %]
[%###########################################################################%]
[%# Block for depth control toolbar #%]
[%###########################################################################%]
[% BLOCK depthControlToolbar %]
<table cellpadding="3" border="0" cellspacing="0" bgcolor="#d0d0d0">
<tr>
[%# Hide/show resolved button
Swaps text depending on the state of hide_resolved %]
<td align="center">
<form method="get" action="showdependencytree.cgi"
style="display: inline; margin: 0px;">
<input name="id" type="hidden" value="[% bugid %]">
[% IF maxdepth %]
<input name="maxdepth" type="hidden" value="[% maxdepth %]">
[% END %]
<input type="hidden" name="hide_resolved" value="[% hide_resolved ? 0 : 1 %]">
<input type="submit" value="[% hide_resolved ? "Show" : "Hide" %] Resolved">
</form>
</td>
<td>
Max Depth:
</td>
<td>
&nbsp;
</td>
<td>
<form method="get" action="showdependencytree.cgi"
style="display: inline; margin: 0px;">
[%# set to one form %]
<input type="submit" value="&nbsp;1&nbsp;" [%
realdepth < 2 || maxdepth == 1 ? "disabled" : ""
%]>
<input name="id" type="hidden" value="[% bugid %]">
<input name="maxdepth" type="hidden" value="1">
<input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
</form>
</td>
<td>
<form method="get" action="showdependencytree.cgi"
style="display: inline; margin: 0px;">
[%# Minus one form
Allow subtracting only when realdepth and maxdepth > 1 %]
<input name="id" type="hidden" value="[% bugid %]">
<input name="maxdepth" type="hidden" value="[%
maxdepth == 1 ? 1
: ( maxdepth ? maxdepth - 1 : realdepth - 1 )
%]">
<input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
<input type="submit" value="&nbsp;&lt;&nbsp;" [%
realdepth < 2 || ( maxdepth && maxdepth < 2 ) ? "disabled" : ""
%]>
</form>
</td>
<td>
<form method="get" action="showdependencytree.cgi"
style="display: inline; margin: 0px;">
[%# Limit entry form: the button can not do anything when total depth
is less than two, so disable it %]
<input name="maxdepth" size="4" maxlength="4" value="[%
maxdepth > 0 ? maxdepth : ""
%]">
<input name="id" type="hidden" value="[% bugid %]">
<input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
<noscript>
<input type="submit" value="Change" [% realdepth < 2 ? "disabled" : "" %]>
</noscript>
</form>
</td>
<td>
<form method="get" action="showdependencytree.cgi"
style="display: inline; margin: 0px;">
[%# plus one form
Disable button if total depth < 2, or if depth set to unlimited %]
<input name="id" type="hidden" value="[% bugid %]">
[% IF maxdepth %]
<input name="maxdepth" type="hidden" value="[% maxdepth + 1 %]">
[% END %]
<input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
<input type="submit" value="&nbsp;&gt;&nbsp;" [%
realdepth < 2 || ! maxdepth || maxdepth >= realdepth ?
"disabled" : ""
%]>
</form>
</td>
<td>
<form method="get" action="showdependencytree.cgi"
style="display: inline; margin: 0px;">
[%# Unlimited button %]
<input name="id" type="hidden" value="[% bugid %]">
<input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
<input type="submit" value="&nbsp;Unlimited&nbsp;">
</form>
</td>
</tr>
</table>
[% END %]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment