turned on): target_milestone, qa_contact, and status_whiteboard.
+1/20/99 Added new fields: Target Milestone, QA Contact, and Status Whiteboard.
+These fields are all optional in the UI; there are parameters to turn them on.
+However, whether or not you use them, the fields need to be in the DB. There
+is some code that needs them, even if you don't.
+
+To update your DB to have these fields, send the following to MySQL:
+
+ alter table bugs add column target_milestone varchar(20) not null,
+ add column qa_contact mediumint not null,
+ add column status_whiteboard mediumtext not null,
+ add index (target_milestone), add index (qa_contact);
+
+
+
1/18/99 You can now query by CC. To make this perform reasonably, the CC table
needs some indices. The following MySQL does the necessary stuff:
reporter,
bug_file_loc,
short_desc,
+ target_milestone,
+ qa_contact,
+ status_whiteboard,
date_format(creation_ts,'Y-m-d')
from bugs
where bug_id = $::FORM{'id'}";
foreach my $field ("bug_id", "product", "version", "rep_platform",
"op_sys", "bug_status", "resolution", "priority",
"bug_severity", "component", "assigned_to", "reporter",
- "bug_file_loc", "short_desc", "creation_ts") {
+ "bug_file_loc", "short_desc", "target_milestone",
+ "qa_contact", "status_whiteboard", "creation_ts") {
$bug{$field} = shift @row;
if (!defined $bug{$field}) {
$bug{$field} = "";
</TR><TR>
<TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#assigned_to\">Assigned To:
</A></B></TD>
- <TD>$bug{'assigned_to'}</TD>
- </TR><TR>
+ <TD>$bug{'assigned_to'}</TD>";
+
+if (Param("usetargetmilestone")) {
+ if ($bug{'target_milestone'} eq "") {
+ $bug{'target_milestone'} = " ";
+ }
+ print "
+<TD ALIGN=RIGHT><B>Target Milestone:</B></TD>
+<TD><SELECT NAME=target_milestone>" .
+ make_options(\@::legal_target_milestone,
+ $bug{'target_milestone'}) .
+ "</SELECT></TD>";
+}
+
+print "
+</TR>";
+
+if (Param("useqacontact")) {
+ my $name = $bug{'qa_contact'} > 0 ? DBID_to_name($bug{'qa_contact'}) : "";
+ print "
+ <TR>
+ <TD ALIGN=\"RIGHT\"><B>QA Contact:</B>
+ <TD COLSPAN=6>
+ <INPUT NAME=qa_contact VALUE=\"" .
+ value_quote($name) .
+ "\" SIZE=60></
+ </TR>";
+}
+
+
+print "
+ <TR>
<TD ALIGN=\"RIGHT\">$URL
<TD COLSPAN=6>
<INPUT NAME=bug_file_loc VALUE=\"$bug{'bug_file_loc'}\" SIZE=60></TD>
<INPUT NAME=short_desc VALUE=\"" .
value_quote($bug{'short_desc'}) .
"\" SIZE=60></TD>
- </TR>
+ </TR>";
+
+if (Param("usestatuswhiteboard")) {
+ print "
+ <TR>
+ <TD ALIGN=\"RIGHT\"><B>Status Whiteboard:</B>
+ <TD COLSPAN=6>
+ <INPUT NAME=status_whiteboard VALUE=\"" .
+ value_quote($bug{'status_whiteboard'}) .
+ "\" SIZE=60></
+ </TR>";
+}
+
+
+print "
</TABLE>
<br>
<B>Additional Comments:</B>
navigation_header();
print "</BODY>\n";
+
+1;
@::legal_severity,
@::legal_priority,
@::default_column_list,
- @::legal_resolution_no_dup;
+ @::legal_resolution_no_dup,
+ @::legal_target_milestone;
"bugs.rep_platform");
DefCol("owner", "assign.login_name", "Owner", "assign.login_name");
DefCol("reporter", "report.login_name", "Reporter", "report.login_name");
+DefCol("qa_contact", "qacont.login_name", "QAContact", "qacont.login_name");
DefCol("status", "substring(bugs.bug_status,1,4)", "State", "bugs.bug_status");
DefCol("resolution", "substring(bugs.resolution,1,4)", "Result",
"bugs.resolution");
DefCol("summary", "substring(bugs.short_desc, 1, 60)", "Summary", "", 1);
DefCol("summaryfull", "bugs.short_desc", "Summary", "", 1);
+DefCol("status_whiteboard", "bugs.status_whiteboard", "StatusSummary", "", 1);
DefCol("component", "substring(bugs.component, 1, 8)", "Comp",
"bugs.component");
DefCol("product", "substring(bugs.product, 1, 8)", "Product", "bugs.product");
DefCol("version", "substring(bugs.version, 1, 5)", "Vers", "bugs.version");
DefCol("os", "substring(bugs.op_sys, 1, 4)", "OS", "bugs.op_sys");
+DefCol("target_milestone", "bugs.target_milestone", "TargetM",
+ "bugs.target_milestone");
my @collist;
if (defined $::COOKIE{'COLUMNLIST'}) {
$query .= "
from bugs,
profiles assign,
- profiles report,
+ profiles report
+ left join profiles qacont on bugs.qa_contact = qacont.userid,
versions projector
where bugs.assigned_to = assign.userid
and bugs.reporter = report.userid
} else {
my @legal_fields = ("bug_id", "product", "version", "rep_platform", "op_sys",
"bug_status", "resolution", "priority", "bug_severity",
- "assigned_to", "reporter", "component");
+ "assigned_to", "reporter", "component",
+ "target_milestone");
foreach my $field (keys %::FORM) {
my $or = "";
my $foundone = 0;
my $lead= "and (\n";
- foreach my $field ("assigned_to", "reporter", "cc") {
+ foreach my $field ("assigned_to", "reporter", "cc", "qa_contact") {
my $doit = $::FORM{"email$field$id"};
if (!$doit) {
next;
$table = "assign";
} elsif ($field eq "reporter") {
$table = "report";
+ } elsif ($field eq "qa_contact") {
+ $table = "qacont";
} else {
$table = "ccname";
}
<TD><SELECT NAME=component>$component_popup</SELECT></TD>
<TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#severity\">Severity:</A></B></TD>
<TD><SELECT NAME=bug_severity>$sev_popup</SELECT></TD>
-</TR>
+</TR>";
+
+ if (Param("usetargetmilestone")) {
+ my $tfm_popup = make_options(\@::legal_target_milestone,
+ $::dontchange);
+ print "
+ <TR>
+ <TD ALIGN=RIGHT><B>Target milestone:</B></TD>
+ <TD><SELECT NAME=target_milestone>$tfm_popup</SELECT></TD>
+ </TR>";
+ }
+
+ if (Param("useqacontact")) {
+ print "
+<TR>
+<TD><B>QA Contact:</B></TD>
+<TD COLSPAN=3><INPUT NAME=qa_contact SIZE=32 VALUE=\"" .
+ value_quote($::dontchange) . "\"></TD>
+</TR>";
+ }
+
+
+ print "
</TABLE>
<INPUT NAME=multiupdate value=Y TYPE=hidden>
my @masterlist = ("opendate", "changeddate", "severity", "priority",
"platform", "owner", "reporter", "status", "resolution",
- "component", "product", "version", "project", "os",
- "summary", "summaryfull");
+ "component", "product", "version", "project", "os");
+
+if (Param("usetargetmilestone")) {
+ push(@masterlist, "target_milestone");
+}
+if (Param("useqacontact")) {
+ push(@masterlist, "qa_contact");
+}
+if (Param("usestatuswhiteboard")) {
+ push(@masterlist, "status_whiteboard");
+}
+
+
+push(@masterlist, ("summary", "summaryfull"));
my @collist;
foreach my $i (@::param_list) {
if (!defined $::param{$i}) {
$::param{$i} = $::param_default{$i};
+ if (!defined $::param{$i}) {
+ die "No default parameter ever specified for $i";
+ }
}
}
mkdir("data", 0777);
my $tmpname = "data/params.$$";
open(FID, ">$tmpname") || die "Can't create $tmpname";
my $v = $::param{'version'};
- undef $::param{'version'}; # Don't write the version number out to
+ delete $::param{'version'}; # Don't write the version number out to
# the params file.
print FID GenerateCode('%::param');
$::param{'version'} = $v;
# t -- A short text entry field (suitable for a single line)
# l -- A long text field (suitable for many lines)
# b -- A boolean value (either 1 or 0)
+# i -- An integer.
# defenum -- This param defines an enum that defines a column in one of
# the database tables. The name of the parameter is of the form
# "tablename.columnname".
"t",
"bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=Mozilla&order=%22Importance%22");
+DefParam("usetargetmilestone",
+ "Do you wish to use the Target Milestone field?",
+ "b",
+ 0);
+
+DefParam("nummilestones",
+ "If using Target Milestone, how many milestones do you wish to
+ appear?",
+ "t",
+ 10,
+ \&check_numeric);
+
+DefParam("useqacontact",
+ "Do you wish to use the QA Contact field?",
+ "b",
+ 0);
+
+DefParam("usestatuswhiteboard",
+ "Do you wish to use the Status Whiteboard field?",
+ "b",
+ 0);
+
+
+
+
1;
+
WriteParams();
+unlink "data/versioncache";
+
print "OK, done.<p>\n";
print "<a href=editparams.cgi>Edit the params some more.</a><p>\n";
print "<a href=query.cgi>Go back to the query page.</a>\n";
SWITCH: for ($::param_type{$i}) {
/^t$/ && do {
print "<input size=80 name=$i value=\"" .
- value_quote($value) . '">\n';
+ value_quote($value) . "\">\n";
last SWITCH;
};
/^l$/ && do {
use Mysql;
use Date::Format; # For time2str().
+# use Carp; # for confess
# Contains the version string for the current running Bugzilla.
$::param{'version'} = '2.1';
}
print FID GenerateCode('%::proddesc');
+ if (Param("usetargetmilestone")) {
+ my $last = Param("nummilestones");
+ my $i;
+ for ($i=1 ; $i<=$last ; $i++) {
+ push(@::legal_target_milestone, "M$i");
+ }
+ print FID GenerateCode('@::legal_target_milestone');
+ }
print FID "1;\n";
close FID;
rename $tmpname, "data/versioncache" || die "Can't rename $tmpname to versioncache";
sub SqlQuote {
my ($str) = (@_);
+# if (!defined $str) {
+# confess("Undefined passed to SqlQuote");
+# }
$str =~ s/([\\\'])/\\$1/g;
$str =~ s/\0/\\0/g;
return "'$str'";
report.login_name,
bugs.component,
bugs.bug_file_loc,
- bugs.short_desc
+ bugs.short_desc,
+ bugs.target_milestone,
+ bugs.qa_contact,
+ bugs.status_whiteboard
from bugs,profiles assign,profiles report
where assign.userid = bugs.assigned_to and report.userid = bugs.reporter and
";
if (@row = FetchSQLData()) {
my ($id, $product, $version, $platform, $opsys, $status, $severity,
$priority, $resolution, $assigned, $reporter, $component, $url,
- $shortdesc) = (@row);
+ $shortdesc, $target_milestone, $qa_contact,
+ $status_whiteboard) = (@row);
print "<IMG SRC=\"1x1.gif\" WIDTH=1 HEIGHT=80 ALIGN=LEFT>\n";
print "<TABLE WIDTH=100%>\n";
print "<TD COLSPAN=4><TR><DIV ALIGN=CENTER><B><FONT =\"+3\">" .
print "<TR><TD><B>Resolution:</B> $resolution</TD>\n";
print "<TD><B>Assigned To:</B> $assigned\n";
print "<TD><B>Reported By:</B> $reporter\n";
+ if (Param("useqacontact")) {
+ my $name = "";
+ if ($qa_contact > 0) {
+ $name = DBID_to_name($qa_contact);
+ }
+ print "<TD><B>QA Contact:</B> $name\n";
+ }
print "<TR><TD><B>Component:</B> $component\n";
+ if (Param("usetargetmilestone")) {
+ print "<TD><B>Target milestone:</B>$target_milestone\n";
+ }
print "<TR><TD COLSPAN=6><B>URL:</B> " . html_quote($url) . "\n";
- print "<TR><TD COLSPAN=6><B>Summary :</B> " . html_quote($shortdesc) . "\n";
- print "<TR><TD><B>Description :</B>\n</TABLE>\n";
+ print "<TR><TD COLSPAN=6><B>Summary:</B> " . html_quote($shortdesc) . "\n";
+ if (Param("usestatuswhiteboard")) {
+ print "<TR><TD COLSPAN=6><B>Status Whiteboard:" .
+ html_quote($status_whiteboard) . "\n";
+ }
+ print "<TR><TD><B>Description:</B>\n</TABLE>\n";
print "<PRE>" . html_quote(GetLongDescription($bug)) . "</PRE>\n";
print "<HR>\n";
}
area enum("BUILD", "CODE", "CONTENT", "DOC", "PERFORMANCE", "TEST", "UI", "i18n", "l10n") not null,
component varchar(50) not null,
resolution enum("", "FIXED", "INVALID", "WONTFIX", "LATER", "REMIND", "DUPLICATE", "WORKSFORME") not null,
-
+target_milestone varchar(20) not null,
+qa_contact mediumint not null,
+status_whiteboard mediumtext not null,
index (assigned_to),
index (delta_ts),
index (version),
index (area),
index (component),
-index (resolution)
+index (resolution),
+index (target_milestone),
+index (qa_contact)
);
foreach my $field ("rep_platform", "priority", "bug_severity", "url",
"summary", "component", "bug_file_loc", "short_desc",
- "product", "version", "component", "op_sys") {
+ "product", "version", "component", "op_sys",
+ "target_milestone", "status_whiteboard") {
if (defined $::FORM{$field}) {
if ($::FORM{$field} ne $::dontchange) {
DoComma();
- $::query .= "$field = " . SqlQuote($::FORM{$field});
+ $::query .= "$field = " . SqlQuote(trim($::FORM{$field}));
}
}
}
+if (defined $::FORM{'qa_contact'}) {
+ my $name = trim($::FORM{'qa_contact'});
+ if ($name ne $dontchange) {
+ my $id = 0;
+ if ($name ne "") {
+ $id = DBNameToIdAndCheck($name);
+ }
+ DoComma();
+ $::query .= "qa_contact = $id";
+ }
+}
+
ConnectToDatabase();
@::legal_components,
@::legal_versions,
@::legal_severity,
+ @::legal_target_milestone,
%::FORM;
"priority", "bug_severity", "product", "reporter", "op_sys",
"component", "version",
"email1", "emailtype1", "emailreporter1",
- "emailassigned_to1", "emailcc1",
+ "emailassigned_to1", "emailcc1", "emailqa_contact1",
"email2", "emailtype2", "emailreporter2",
- "emailassigned_to2", "emailcc2") {
+ "emailassigned_to2", "emailcc2", "emailqa_contact2") {
$default{$name} = "";
$type{$name} = 0;
}
}
}
+ my $qapart = "";
+ if (Param("useqacontact")) {
+ my $qacontact =
+ ($default{"emailqa_contact$id"} eq "1") ? "checked" : "";
+ $qapart = qq|
+<tr>
+<td></td>
+<td>
+<input type="checkbox" name="emailqa_contact$id" value=1 $qacontact>QA Contact
+</td>
+</tr>
+|;
+ }
+
return qq|
<table border=1 cellspacing=0 cellpadding=0>
<tr><td>
<td>
<input type="checkbox" name="emailreporter$id" value=1 $reporter>Reporter
</td>
-</tr>
+</tr>$qapart
<tr>
<td align=right>(Will match any of the selected fields)</td>
<td>
<table>
<tr>
-<TH ALIGN=LEFT>Program:</th>
-<TH ALIGN=LEFT>Version:</th>
-<TH ALIGN=LEFT>Component:</th>
+<TH ALIGN=LEFT VALIGN=BOTTOM>Program:</th>
+<TH ALIGN=LEFT VALIGN=BOTTOM>Version:</th>
+<TH ALIGN=LEFT VALIGN=BOTTOM>Component:</th>
+";
+
+if (Param("usetargetmilestone")) {
+ print "<TH ALIGN=LEFT VALIGN=BOTTOM>Target Milestone:</th>";
+}
+
+print "
</tr>
<tr>
<SELECT NAME=\"component\" MULTIPLE SIZE=5>
@{[make_options(\@::legal_components, $default{'component'}, $type{'component'})]}
</SELECT>
-</td>
+</td>";
+if (Param("usetargetmilestone")) {
+ print "
+<td align=left valign=top>
+<SELECT NAME=\"target_milestone\" MULTIPLE SIZE=5>
+@{[make_options(\@::legal_target_milestone, $default{'component'}, $type{'component'})]}
+</SELECT>
+</td>";
+}
+
+print "
</tr>
</table>
<td><input type=radio name=long_desc_type value=substr checked>Substring</td>
<td><input type=radio name=long_desc_type value=regexp>Regexp</td>
</tr>
+<tr>
<td align=right>URL:</td>
<td><input name=bug_file_loc size=30></td>
<td><input type=radio name=bug_file_loc_type value=substr checked>Substring</td>
<td><input type=radio name=bug_file_loc_type value=regexp>Regexp</td>
-</tr>
+</tr>";
+
+if (Param("usestatuswhiteboard")) {
+ print "
+<tr>
+<td align=right>Status whiteboard:</td>
+<td><input name=status_whiteboard size=30></td>
+<td><input type=radio name=status_whiteboard_type value=substr checked>Substring</td>
+<td><input type=radio name=status_whiteboard_type value=regexp>Regexp</td>
+</tr>";
+}
+
+print "
</table>
<p>
print "<HR>\n";
-do "bug_form.pl";
+$! = 0;
+do "bug_form.pl" || die "Error doing bug_form.pl: $!";