Added name field and admin indication to bug tracker
This commit is contained in:
parent
874e1825ec
commit
fa28f26d69
3 changed files with 40 additions and 14 deletions
48
Bug.pm
48
Bug.pm
|
|
@ -15,9 +15,16 @@
|
||||||
status varchar NOT NULL DEFAULT '',
|
status varchar NOT NULL DEFAULT '',
|
||||||
closed boolean NOT NULL DEFAULT false,
|
closed boolean NOT NULL DEFAULT false,
|
||||||
email varchar NOT NULL DEFAULT '',
|
email varchar NOT NULL DEFAULT '',
|
||||||
message varchar NOT NULL DEFAULT ''
|
message varchar NOT NULL DEFAULT '',
|
||||||
|
admin boolean NOT NULL DEFAULT false,
|
||||||
|
name varchar(200) NOT NULL DEFAULT ''
|
||||||
);
|
);
|
||||||
|
|
||||||
|
=head2 Update queries
|
||||||
|
|
||||||
|
ALTER TABLE ${p}messages ADD COLUMN admin boolean NOT NULL DEFAULT false;
|
||||||
|
ALTER TABLE ${p}messages ADD COLUMN name varchar(200) NOT NULL DEFAULT '';
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
# TODO: Atom feed?
|
# TODO: Atom feed?
|
||||||
|
|
@ -71,7 +78,7 @@ sub dbListing {
|
||||||
sub dbItem {
|
sub dbItem {
|
||||||
my($self, $id) = @_;
|
my($self, $id) = @_;
|
||||||
return $TUWF::OBJ->dbAll(q{
|
return $TUWF::OBJ->dbAll(q{
|
||||||
SELECT m.issue, m.summary, to_char(m.date, 'YYYY-MM-DD HH24:MI:SS (tz)') AS date, m.type, m.status, m.closed, m.message
|
SELECT m.issue, m.summary, to_char(m.date, 'YYYY-MM-DD HH24:MI:SS (tz)') AS date, m.type, m.status, m.closed, m.name, m.admin, m.message
|
||||||
FROM !smessages m
|
FROM !smessages m
|
||||||
WHERE m.issue = ?
|
WHERE m.issue = ?
|
||||||
ORDER BY m.id}, $self->{prefix}, $id
|
ORDER BY m.id}, $self->{prefix}, $id
|
||||||
|
|
@ -89,7 +96,7 @@ sub dbSave {
|
||||||
my($self, $id, $closed, @a) = @_;
|
my($self, $id, $closed, @a) = @_;
|
||||||
$id = $TUWF::OBJ->dbRow('INSERT INTO !sissues (latest) VALUES (0) RETURNING issue', $self->{prefix})->{issue} if !$id;
|
$id = $TUWF::OBJ->dbRow('INSERT INTO !sissues (latest) VALUES (0) RETURNING issue', $self->{prefix})->{issue} if !$id;
|
||||||
my $latest = $TUWF::OBJ->dbRow(
|
my $latest = $TUWF::OBJ->dbRow(
|
||||||
'INSERT INTO !smessages (issue, closed, summary, email, type, status, message) VALUES (?, ?, !l) RETURNING id',
|
'INSERT INTO !smessages (issue, closed, summary, name, email, type, status, message, admin) VALUES (?, ?, !l) RETURNING id',
|
||||||
$self->{prefix}, $id, $closed?1:0, \@a
|
$self->{prefix}, $id, $closed?1:0, \@a
|
||||||
)->{id};
|
)->{id};
|
||||||
$TUWF::OBJ->dbExec('UPDATE !sissues SET latest = ? WHERE issue = ?', $self->{prefix}, $latest, $id);
|
$TUWF::OBJ->dbExec('UPDATE !sissues SET latest = ? WHERE issue = ?', $self->{prefix}, $latest, $id);
|
||||||
|
|
@ -150,7 +157,12 @@ sub htmlItem {
|
||||||
div class => 'bug_message';
|
div class => 'bug_message';
|
||||||
h1 !++$num ? 'Description' : "Reply $num";
|
h1 !++$num ? 'Description' : "Reply $num";
|
||||||
dl;
|
dl;
|
||||||
dt !$num ? 'Created' : 'Added'; dd $m->{date};
|
dt !$num ? 'Created' : 'Added';
|
||||||
|
dd;
|
||||||
|
txt "$m->{date} by ";
|
||||||
|
txt $m->{name}||'Anonymous' if !$m->{admin};
|
||||||
|
b $m->{name}||'Admin' if $m->{admin};
|
||||||
|
end;
|
||||||
for($num ? qw|summary type status| : ()) {
|
for($num ? qw|summary type status| : ()) {
|
||||||
if($m->{$_} ne $d->[$num-1]{$_}) {
|
if($m->{$_} ne $d->[$num-1]{$_}) {
|
||||||
dt "\u$_";
|
dt "\u$_";
|
||||||
|
|
@ -181,9 +193,15 @@ sub htmlForm {
|
||||||
label for => 'bug_summary', 'Summary';
|
label for => 'bug_summary', 'Summary';
|
||||||
input type => 'text', name => 'bug_summary', id => 'bug_summary', size => 45, value => $l?$l->{summary}:'';
|
input type => 'text', name => 'bug_summary', id => 'bug_summary', size => 45, value => $l?$l->{summary}:'';
|
||||||
end;
|
end;
|
||||||
|
li class => 'bug_frm_name';
|
||||||
|
label for => 'bug_name', 'Name';
|
||||||
|
input type => 'text', name => 'bug_name', id => 'bug_name', size => 20, value => $TUWF::OBJ->reqCookie('bug_name')||'';
|
||||||
|
lit ' ';
|
||||||
|
txt 'Name+email will be remembered with a cookie.';
|
||||||
|
end;
|
||||||
li class => 'bug_frm_mail';
|
li class => 'bug_frm_mail';
|
||||||
label for => 'bug_email', 'Email';
|
label for => 'bug_email', 'Email';
|
||||||
input type => 'text', name => 'bug_email', id => 'bug_email', size => 20;
|
input type => 'text', name => 'bug_email', id => 'bug_email', size => 20, value => $TUWF::OBJ->reqCookie('bug_email')||'';
|
||||||
lit ' ';
|
lit ' ';
|
||||||
txt 'Optional, only used for notifications.';
|
txt 'Optional, only used for notifications.';
|
||||||
end;
|
end;
|
||||||
|
|
@ -200,7 +218,7 @@ sub htmlForm {
|
||||||
option value => 0, !$l->{closed} ? (selected => 'selected') : (), 'Open';
|
option value => 0, !$l->{closed} ? (selected => 'selected') : (), 'Open';
|
||||||
option value => 1, $l->{closed} ? (selected => 'selected') : (), 'Closed';
|
option value => 1, $l->{closed} ? (selected => 'selected') : (), 'Closed';
|
||||||
end;
|
end;
|
||||||
input type => 'password', name => 'bug_code', id => 'bug_code', size => 10, value => 'code';
|
input type => 'password', name => 'bug_code', id => 'bug_code', size => 10, value => $TUWF::OBJ->reqCookie('bug_code')||'code';
|
||||||
end;
|
end;
|
||||||
} else {
|
} else {
|
||||||
li class => 'bug_frm_type';
|
li class => 'bug_frm_type';
|
||||||
|
|
@ -228,12 +246,16 @@ sub handleForm {
|
||||||
my $f = $TUWF::OBJ->formValidate(
|
my $f = $TUWF::OBJ->formValidate(
|
||||||
{ post => 'bug_id', min => 0 },
|
{ post => 'bug_id', min => 0 },
|
||||||
{ post => 'bug_summary', maxlength => 200, minlength => 2 },
|
{ post => 'bug_summary', maxlength => 200, minlength => 2 },
|
||||||
|
{ post => 'bug_name', required => 0, default => '', maxlength => 200 },
|
||||||
{ post => 'bug_email', required => 0, regex => qr/^[^@<>]+@[^@.<>]+(?:\.[^@.<>]+)+$/ },
|
{ post => 'bug_email', required => 0, regex => qr/^[^@<>]+@[^@.<>]+(?:\.[^@.<>]+)+$/ },
|
||||||
{ post => 'bug_code', required => 0, default => '' },
|
{ post => 'bug_code', required => 0, default => '' },
|
||||||
{ post => 'bug_message', maxlength => 256*1024, minlength => 1 },
|
{ post => 'bug_message', maxlength => 256*1024, minlength => 1 },
|
||||||
);
|
);
|
||||||
return($f, undef) if $f->{_err};
|
return($f, undef) if $f->{_err};
|
||||||
|
|
||||||
|
$f->{bug_code} = '' if $f->{bug_code} eq 'code';
|
||||||
|
my $admin = grep($_ eq $f->{bug_code}, @{$s->{admins}}) ? 1 : 0;
|
||||||
|
|
||||||
my $l;
|
my $l;
|
||||||
# Reply
|
# Reply
|
||||||
if($f->{bug_id} > 0) {
|
if($f->{bug_id} > 0) {
|
||||||
|
|
@ -241,7 +263,7 @@ sub handleForm {
|
||||||
push @{$f->{_err}}, ['bug_id', 'db_check', ''] and return($f, undef) if !$l;
|
push @{$f->{_err}}, ['bug_id', 'db_check', ''] and return($f, undef) if !$l;
|
||||||
|
|
||||||
# Check admin things
|
# Check admin things
|
||||||
if(grep $_ eq $f->{bug_code}, @{$s->{admins}}) {
|
if($admin) {
|
||||||
my $fa = $TUWF::OBJ->formValidate(
|
my $fa = $TUWF::OBJ->formValidate(
|
||||||
{ post => 'bug_type', enum => $s->{types} },
|
{ post => 'bug_type', enum => $s->{types} },
|
||||||
{ post => 'bug_status', enum => $s->{statusses} },
|
{ post => 'bug_status', enum => $s->{statusses} },
|
||||||
|
|
@ -250,7 +272,7 @@ sub handleForm {
|
||||||
$f = { %$f, %$fa };
|
$f = { %$f, %$fa };
|
||||||
return($f, $l) if $f->{_err};
|
return($f, $l) if $f->{_err};
|
||||||
} else {
|
} else {
|
||||||
push @{$f->{_err}}, [ 'bug_code', 'invalid', '' ] and return($f, undef) if $f->{bug_code} && $f->{bug_code} ne 'code';
|
push @{$f->{_err}}, [ 'bug_code', 'invalid', '' ] and return($f, undef) if $f->{bug_code};
|
||||||
$f->{bug_type} = $l->{type};
|
$f->{bug_type} = $l->{type};
|
||||||
$f->{bug_status} = $l->{status};
|
$f->{bug_status} = $l->{status};
|
||||||
$f->{bug_closed} = $l->{closed};
|
$f->{bug_closed} = $l->{closed};
|
||||||
|
|
@ -266,18 +288,20 @@ sub handleForm {
|
||||||
}
|
}
|
||||||
|
|
||||||
# No errors? Save!
|
# No errors? Save!
|
||||||
my $id = $s->dbSave(map $f->{"bug_$_"}, qw|id closed summary email type status message|);
|
my $id = $s->dbSave(map($f->{"bug_$_"}, qw|id closed summary name email type status message|), $admin);
|
||||||
|
|
||||||
|
my $u = $url->($id);
|
||||||
|
|
||||||
# For replies, send out notification emails
|
# For replies, send out notification emails
|
||||||
if($l) {
|
if($l) {
|
||||||
my $mails = $s->dbEmails($id);
|
my $mails = $s->dbEmails($id);
|
||||||
my $u = $url->($id);
|
my $base = $TUWF::OBJ->reqBaseURI();
|
||||||
for(grep $_ ne $f->{bug_email}, @$mails) {
|
for(grep $_ ne $f->{bug_email}, @$mails) {
|
||||||
$TUWF::OBJ->mail(
|
$TUWF::OBJ->mail(
|
||||||
"Hello!\n\n".
|
"Hello!\n\n".
|
||||||
"A new reply has been posted to an bug you have previously shown\n".
|
"A new reply has been posted to an bug you have previously shown\n".
|
||||||
"an interest in. You can view the reply at the following URL:\n".
|
"an interest in. You can view the reply at the following URL:\n".
|
||||||
" $u\n\n".
|
" $base$u\n\n".
|
||||||
"If you do not wish to receive any more notifications for this (and\n".
|
"If you do not wish to receive any more notifications for this (and\n".
|
||||||
"perhaps other) bugs, please reply to this email stating your intent.",
|
"perhaps other) bugs, please reply to this email stating your intent.",
|
||||||
Subject => "Reply to $f->{bug_summary}",
|
Subject => "Reply to $f->{bug_summary}",
|
||||||
|
|
@ -287,6 +311,8 @@ sub handleForm {
|
||||||
}
|
}
|
||||||
|
|
||||||
$l = $s->dbListing(id => $id)->[0] if !$l;
|
$l = $s->dbListing(id => $id)->[0] if !$l;
|
||||||
|
$TUWF::OBJ->resRedirect($u, 'post');
|
||||||
|
$f->{$_} and $TUWF::OBJ->resCookie($_ => $f->{$_}, expires => time()+365*24*3600) for ('bug_name', 'bug_email', 'bug_code');
|
||||||
|
|
||||||
return($f, $l);
|
return($f, $l);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,7 @@ TUWF::set(
|
||||||
mail_from => 'Yorhels Bug Tracker <projects@yorhel.nl>',
|
mail_from => 'Yorhels Bug Tracker <projects@yorhel.nl>',
|
||||||
# this is a fairly static site, allow some aggressive caching
|
# this is a fairly static site, allow some aggressive caching
|
||||||
pre_request_handler => sub { $_[0]->resHeader('Cache-Control', 's-max-age=86400, max-age=3600'); 1; },
|
pre_request_handler => sub { $_[0]->resHeader('Cache-Control', 's-max-age=86400, max-age=3600'); 1; },
|
||||||
|
cookie_defaults => { domain => 'dev.yorhel.nl', path => '/' },
|
||||||
);
|
);
|
||||||
|
|
||||||
TUWF::run();
|
TUWF::run();
|
||||||
|
|
@ -245,7 +246,7 @@ sub bug_post {
|
||||||
my($s, $p) = @_;
|
my($s, $p) = @_;
|
||||||
return $s->resNotFound if $s->reqMethod() ne 'POST';
|
return $s->resNotFound if $s->reqMethod() ne 'POST';
|
||||||
my $is = _bug_init($s, $p);
|
my $is = _bug_init($s, $p);
|
||||||
my($f, $l) = $is->handleForm(sub { "http://dev.yorhel.nl/$p/bug/".shift });
|
my($f, $l) = $is->handleForm(sub { "/$p/bug/".shift });
|
||||||
|
|
||||||
if($f->{_err}) {
|
if($f->{_err}) {
|
||||||
$s->htmlHeader(title => 'Error creating message', page => $p, sec => 'bug');
|
$s->htmlHeader(title => 'Error creating message', page => $p, sec => 'bug');
|
||||||
|
|
@ -279,8 +280,6 @@ sub bug_post {
|
||||||
});
|
});
|
||||||
$done->recv;
|
$done->recv;
|
||||||
}
|
}
|
||||||
|
|
||||||
$s->resRedirect("/$p/bug/$l->{issue}", 'post');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ table thead td { font-weight: bold }
|
||||||
.bug_item h1 { margin-top: 30px }
|
.bug_item h1 { margin-top: 30px }
|
||||||
.bug_item dt { clear: left; float: left; font-weight: bold; width: 60px }
|
.bug_item dt { clear: left; float: left; font-weight: bold; width: 60px }
|
||||||
.bug_item dd { float: left; padding-right: 20px }
|
.bug_item dd { float: left; padding-right: 20px }
|
||||||
|
.bug_item dd b { color: #a20 }
|
||||||
.bug_item p { clear: left; padding-top: 5px }
|
.bug_item p { clear: left; padding-top: 5px }
|
||||||
.bug_frm fieldset { border: 0; margin-top: 40px }
|
.bug_frm fieldset { border: 0; margin-top: 40px }
|
||||||
.bug_frm legend { font-size: 19px; color: #000; }
|
.bug_frm legend { font-size: 19px; color: #000; }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue