[Bps-public-commit] SD - A distributed issue tracker branch, master, updated. 2be23d9cef3e2f8a9d464b9f449666ac87ea5c96
jesse
jesse at bestpractical.com
Thu Jan 22 21:29:40 EST 2009
The branch, master has been updated
via 2be23d9cef3e2f8a9d464b9f449666ac87ea5c96 (commit)
via 5a01a7b4a8ff04c6f202e42d7745f75ce36fc4db (commit)
from 900f58dcc2bf90ab609fff39abb513052f4bd473 (commit)
Summary of changes:
lib/App/SD/Server/Dispatcher.pm | 1 +
lib/App/SD/Server/View.pm | 238 ++++++++++++++++++++++++++++++---------
2 files changed, 187 insertions(+), 52 deletions(-)
- Log -----------------------------------------------------------------
commit 5a01a7b4a8ff04c6f202e42d7745f75ce36fc4db
Author: Jesse Vincent <jesse at bestpractical.com>
Date: Thu Jan 22 21:29:16 2009 -0500
Improve ticket views in the web ui
diff --git a/lib/App/SD/Server/Dispatcher.pm b/lib/App/SD/Server/Dispatcher.pm
index fc3790d..c92bee9 100644
--- a/lib/App/SD/Server/Dispatcher.pm
+++ b/lib/App/SD/Server/Dispatcher.pm
@@ -65,6 +65,7 @@ under 'GET' => sub {
on 'new' => sub { shift->show_template('new_ticket') };
on qr'^([\w\d-]+)/edit$' => sub { shift->show_template( 'edit_ticket', $1 ) };
+ on qr'^([\w\d-]+)/history$' => sub { shift->show_template( 'show_ticket_history', $1 ) };
on qr'^([\w\d-]+)/?$' => sub { shift->show_template( 'show_ticket', $1 ) };
};
};
diff --git a/lib/App/SD/Server/View.pm b/lib/App/SD/Server/View.pm
index 359e693..0801b2b 100644
--- a/lib/App/SD/Server/View.pm
+++ b/lib/App/SD/Server/View.pm
@@ -12,6 +12,9 @@ use App::SD::Model::Comment;
use App::SD::Collection::Ticket;
+my @BASIC_PROPS = qw(status milestone component owner reporter created due);
+
+
template '/css/sd.css' => sub {
outs_raw( '
@@ -48,8 +51,54 @@ div.project-name {
h1 {
padding: 0.5em;
+ color: #700;
+ font-style: italic;
+ text-decoration: none;
+ font-family: serif;
+ font-size: 1.6em;
+}
+
+h2 {
+ padding: 0.5em;
+ font-style: italic;
+ text-decoration: none;
+ font-family: serif;
font-size: 1.4em;
- background: #ffc;
+
+}
+
+ul.actions {
+ align: center;
+ display: block;
+ min-width: 1em;
+ max-width: 12em;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 0.25em;
+}
+
+ul.actions li {
+ list-style: none;
+ border-right: 1px solid white;
+ padding: 0.25em;
+ display: inline;
+ background: #ddd;
+}
+
+ul.actions li:last-child {
+ border: none;
+}
+
+
+ul.actions li a {
+ text-decoration: none;
+ color: #1133AA;
+ padding: 0.5em;
+ font-size: 0.8em;
+}
+
+ul.actions li:hover {
+ background: #ccc;
}
div.ticket_list ul li span {
@@ -108,14 +157,23 @@ textarea:focus, input:focus {
background-color: #ffc;
}
+div.submit {
+ width: auto;
+ display: block;
+ margin-top: 1em;
+ margin-left: 2em;
+ margin-right: 2em;
+ text-align: right;
+ padding-right: 1em;
+}
+
+
input[type=submit] {
background: #1133AA;
color: #fff;
margin: 0.5em;
padding: 0.5em;
- position: relative;
top: 1em;
- left: 38.5em;
}
input[type=submit]:hover {
background: #002299;
@@ -146,14 +204,38 @@ div.widget div.value {
display: inline-block;
}
+div.comment-form {
+ border-top: 1px solid #999;
+ margin-left: 1em;
+ margin-right: 1em;
+ margin-top: 2em;
+ padding: 2em;
+ padding-top: 0;
+ align: center;
+ background: #eee;
+}
+
+div.comment-form textarea {
+ width: 100%;
+
+}
+
+
div.widget {
padding: 0.5em;
margin-left: 1em;
margin-right: 1em;
border-bottom: 1px solid #ccc;
+}
+
+.widget {
border-top: 1px solid #ccc;
}
+.widget>.widget {
+ border-top: none;
+}
+
ul.page-nav li {
background: #ddd;
border: 0;
@@ -180,14 +262,12 @@ ul.page-nav a {
}
-.widget:nth-child(odd) {
- background: #f5f5f5;
+.widget:nth-child(odd), table.tablesorter tbody tr:nth-child(odd) td {
+ background: #eee;
}
-.widget>.widget {
- border-top: none;
-}
+
dl.history dt {
margin-top: 0.5em;
@@ -243,42 +323,43 @@ ul.comments li:nth-child(odd) {
}
table.tablesorter {
- background: #fff;
- border: none;
-}
-
-
-table.tablesorter {
- width: auto;
+ width: 100%;
+ background: #fff;
+ border: none;
+ position: relative;
+ display: block;
+ border-collapse: collapse;
+ border-spacing: 0;
}
table.tablesorter thead tr th, table.tablesorter tfoot tr th {
padding-right: 2em;
}
-table.tablesorter {
- position: relative;
- display: block;
+table.tablesorter td {
+ border-bottom: 1px solid #ccc;
}
+
table.tablesorter tbody td {
color: #555;
font-weight: bold;
- height: 4.5em;
- padding-top: 2.5em;
+ height: 5em;
+ padding-top: 3em;
}
table.tablesorter td.summary {
margin-top: 0em;
padding: 0;
+ padding-left: 0.25em;
font-weight: normal;
- right:0em;
+ right:1em;
overflow: hidden;
margin-top: 0.5em;
height: 1em;
left: 4.25em;
position: absolute;
padding-bottom: 1.25em;
-
+ border-bottom: none;
}
@@ -292,6 +373,8 @@ table.tablesorter td.summary a, table.tablesorter td.id a {
table.tablesorter td.id {
padding-top: 1.5em;
+ text-align: right;
+ margin-right: 1.5em;
}
table.tablesorter td.id a {
color: #aaa;
@@ -342,8 +425,6 @@ content {
my $self = shift;
my $component = shift;
- h2 {'Open tickets for this component'};
-
$self->show_tickets(
sub {my $item = shift;
( ( $item->prop('component') || '' ) eq $component && $item->has_active_status )
@@ -359,8 +440,6 @@ content {
my $self = shift;
my $milestone = shift;
- h2 {'Open tickets for this milestone'};
-
$self->show_tickets(
sub {my $item = shift;
( ( $item->prop('milestone') || '' ) eq ($milestone || '') && $item->has_active_status )
@@ -408,9 +487,8 @@ template edit_ticket => page {
title is "Update ticket: ". $ticket->luid.": ".$ticket->prop('summary');
- ul { {class is 'actions'};
- li { a {{ href is '/ticket/'.$ticket->uuid.''}; 'Show'}; };
- };
+
+ $self->ticket_page_actions($ticket);
form {
my $f = function(
@@ -423,12 +501,18 @@ template edit_ticket => page {
div { { class is "widget $prop"};
widget( function => $f, prop => $prop, autocomplete => 0 ) };
}
- for my $prop ('status', 'milestone', 'component',
- 'owner', 'due', 'reporter') {
+ for my $prop (@BASIC_PROPS) {
div { { class is "widget $prop"};
widget( function => $f, prop => $prop ) };
}
+
+
+ div { class is 'submit';
+ input { attr { label => 'save', type => 'submit' } };
+ };
+
+ div { class is 'comment-form';
h2 { 'Add a comment' };
my $c = function(
@@ -447,7 +531,10 @@ template edit_ticket => page {
type => 'textarea', autocomplete => 0)};
}
+ };
+ div { class is 'submit';
input { attr { label => 'save', type => 'submit' } };
+ };
};
};
@@ -473,17 +560,20 @@ template new_ticket => page {'Create a new ticket'} content {
}
- for my $prop (
- 'milestone', 'component',
- 'due',
- 'owner',
- 'reporter',
- 'status',
- ) {
+ for my $prop (@BASIC_PROPS) {
div { {class is 'widget '.$prop};
widget( function => $f, prop => $prop ) };
}
+
+
+
+ div { class is 'submit';
+ input { attr { label => 'save', type => 'submit' } };
+ };
+
+
+ div { class is 'comment-form';
h2 { 'Initial comments on this ticket' };
my $c = function(
@@ -505,8 +595,11 @@ template new_ticket => page {'Create a new ticket'} content {
div { widget( function => $c, prop => $prop, type => 'textarea', autocomplete => 0)};
}
+ div { class is 'submit';
input { attr { label => 'save', type => 'submit' } };
- };
+ }
+ }
+ };
};
template footer => sub {
@@ -564,7 +657,8 @@ private template 'ticket_list' => sub {
for my $ticket (@$tickets) {
row {
cell { class is 'id'; ticket_link( $ticket => $ticket->luid ); };
- for (qw(status milestone component owner reporter created due)) {
+ for (@BASIC_PROPS) {
+
cell { class is $_; $ticket->prop($_) };
}
cell { class is 'summary'; ticket_link( $ticket => $ticket->prop('summary') ); };
@@ -580,6 +674,30 @@ private template 'ticket_list' => sub {
};
+template 'show_ticket_history' => page {
+ my $self = shift;
+ my $id = shift;
+ my $ticket = App::SD::Model::Ticket->new(
+ app_handle => $self->app_handle,
+ handle => $self->app_handle->handle
+ );
+ $ticket->load(($id =~ /^\d+$/ ? 'luid' : 'uuid') =>$id);
+
+ $ticket->luid.": ".$ticket->prop('summary');
+ } content {
+ my $self = shift;
+ my $id = shift;
+ my $ticket = App::SD::Model::Ticket->new(
+ app_handle => $self->app_handle,
+ handle => $self->app_handle->handle
+ );
+ $ticket->load(($id =~ /^\d+$/ ? 'luid' : 'uuid') =>$id);
+
+ $self->ticket_page_actions($ticket);
+
+ show ticket_history => $ticket;
+ };
+
template 'show_ticket' => page {
my $self = shift;
my $id = shift;
@@ -598,38 +716,54 @@ template 'show_ticket' => page {
handle => $self->app_handle->handle
);
$ticket->load(($id =~ /^\d+$/ ? 'luid' : 'uuid') =>$id);
- ul { {class is 'actions'};
- li { a {{ href is '/ticket/'.$ticket->uuid.'/edit'}; 'Edit'}; };
- };
+
+ $self->ticket_page_actions($ticket);
+
show ticket_basics => $ticket;
show ticket_attachments => $ticket;
show ticket_comments => $ticket;
- show ticket_history => $ticket;
};
+sub ticket_page_actions {
+ my $self = shift;
+ my $ticket = shift;
+
+ ul { {class is 'actions'};
+ li { a {{ href is '/ticket/'.$ticket->uuid.''}; 'Show'}; };
+ li { a {{ href is '/ticket/'.$ticket->uuid.'/edit'}; 'Update'}; };
+ li { a {{ href is '/ticket/'.$ticket->uuid.'/history'}; 'History'}; };
+ };
+
+
+}
+
+
sub _by_creation_date { $a->prop('created') cmp $b->prop('created') };
private template 'ticket_basics' => sub {
my $self = shift;
my $ticket = shift;
- my $props = $ticket->get_props;
+ my %props = %{$ticket->get_props};
div { { class is 'ticket-props'};
div { class is 'widget';
label { 'UUID' };
div { { class is 'value uuid'}; $ticket->uuid; }
};
- for my $key (sort keys %$props) {
+ for my $key (@BASIC_PROPS, (sort keys %props)) {
+ next unless defined $props{$key};
+ next if ($key eq 'summary');
next if ($key =~ /.{8}-.{4}-.{4}-.{12}-id/);
- div { class is 'widget';
- label{ $key };
- div { { class is 'value '.$key}; $props->{$key};
-
- }
- }
+ div { class is 'widget';
+ label {$key};
+ div { { class is 'value ' . $key }; $props{$key}; }
+ };
+
+ delete $props{$key};
+
}
};
};
commit 2be23d9cef3e2f8a9d464b9f449666ac87ea5c96
Merge: 5a01a7b... 900f58d...
Author: Jesse Vincent <jesse at bestpractical.com>
Date: Thu Jan 22 21:29:37 2009 -0500
Merge branch 'master' of code.bestpractical.com:/git/sd
-----------------------------------------------------------------------
More information about the Bps-public-commit
mailing list