[Bps-public-commit] SD branch, master, updated. 44f9e888e04ec1dc5974525a93b34b07e115ec78
jesse
jesse at bestpractical.com
Thu Jun 18 22:37:06 EDT 2009
The branch, master has been updated
via 44f9e888e04ec1dc5974525a93b34b07e115ec78 (commit)
from a4b0508d1dabcc7b448ffdf51cdc36993adcd423 (commit)
Summary of changes:
lib/App/SD/Server/Dispatcher.pm | 2 +-
lib/App/SD/Server/View.pm | 112 +++++++++++++++++++++++++++++++++------
share/web/static/css/main.css | 74 +++++++++++++++++++++++++
3 files changed, 170 insertions(+), 18 deletions(-)
- Log -----------------------------------------------------------------
commit 44f9e888e04ec1dc5974525a93b34b07e115ec78
Author: Jesse Vincent <jesse at bestpractical.com>
Date: Thu Jun 18 21:36:56 2009 -0500
new homepage for sd webui
diff --git a/lib/App/SD/Server/Dispatcher.pm b/lib/App/SD/Server/Dispatcher.pm
index c7b313f..ee8cc9c 100644
--- a/lib/App/SD/Server/Dispatcher.pm
+++ b/lib/App/SD/Server/Dispatcher.pm
@@ -59,7 +59,7 @@ under { method => 'POST' } => sub {
under { method => 'GET' } => sub {
on qr'^/static/sd/(.*)$' => sub { shift->server->send_static_file($1)};
- on qr'^/(milestone|component)/([\w\d-]+)$' => sub {
+ on qr'^/(milestone|component|status)/([\w\d-]*)$' => sub {
my $name = $1;
my $type = $2;
shift->show_template( $name => $type );
diff --git a/lib/App/SD/Server/View.pm b/lib/App/SD/Server/View.pm
index 7f25e13..a96e623 100644
--- a/lib/App/SD/Server/View.pm
+++ b/lib/App/SD/Server/View.pm
@@ -14,9 +14,29 @@ use App::SD::Collection::Ticket;
my @BASIC_PROPS = qw(status milestone component owner reporter due created tags description);
+sub page_box {
+ my ($id, $title, $component) = (@_);
+ div { { id is $id };
+ { h2 { $title}; show($component)}
+ };
+
+}
+
+template '' => page { 'Project overview'} content {
+ my $self = shift;
+ div { { class is 'stats sidebar'};
+ page_box('components', 'Components', 'component_list');
+ page_box('statuses', 'Statuses', 'status_list');
+ page_box('milestones', 'Milestones', 'milestone_list');
+ };
+ div { { class is 'overview'};
+ h2 { 'Your active tickets for '. $self->app_handle->setting( label => 'default_milestone' )->get()->[0];};
+ show('/tickets/hot');
+ };
+};
-template '/' => page {'My open tickets for the current milestone'}
+template 'hot_tickets' => page {'Your open tickets for the current milestone'}
content {
show('/tickets/hot');
@@ -31,31 +51,83 @@ template 'milestones' => page {'Project milestones'} content {
};
-template 'milestone_list' => sub {
- my $self = shift;
- my $milestones = $self->app_handle->setting( label => 'milestones' )->get();
+template 'status_list' => sub { show('property_list','status'); };
+template 'milestone_list' => sub { show('property_list', 'milestone') };
+template 'component_list' => sub { show('property_list', 'component')};
- div { { class is 'pagesection'};
- ul{
- foreach my $milestone (@$milestones) {
- li {
- a {{ href is '/milestone/'.$milestone} $milestone }
+template 'property_list' => sub {
+ my $self = shift;
+ my $property_name = shift;
+ my $props = $self->app_handle->setting(
+ label => ( $property_name =~ /s$/ ? $property_name . "es" : $property_name . 's' ) )->get();
- }
+ my %counts = map { $_ => 0 } @$props;
+ $self->find_tickets( sub {
+ my $ticket = shift;
+ return if ($property_name ne 'status' && !$ticket->has_active_status);
+ $counts{ $ticket->prop($property_name) || '' }++});
- }
+ my $total = 0;
+ $total += $_ for values %counts;
+
+ div {
+ { class is 'pagesection' };
+ ul {
+
+ my @order = grep {$_ ne ''} keys %counts;
+
+ if ( defined $counts{''} && $counts{''} > 0) {
+ push @order, '';
+ }
+
+
+ foreach my $prop ( @order) {
+ li {
+ div { {class is 'bar-wrapper'} ;
+ div {
+ { class is 'bar'; ($total ? style is ("width: ". int(( ($counts{$prop} ||0)/ $total) * 100 )."%") : ()) };
+ outs(' ');
+ };};
+ outs ( ($counts{$prop} ||'0') . " - ");
+ a {
+ { href is '/' . $property_name . '/' . ($prop ||'') }
+ ( $prop ? $prop : 'None' )
+ }
+
+ }
+
+ }
}
}
};
-template 'no_component' => sub {show 'component' => undef};
-template 'component' => page { 'Component: ' . ( $_[1] || '<i>none</i>' ) }
+
+
+template 'status' => page { 'Status: ' . ( $_[1] || 'none' ) }
+content {
+ my $self = shift;
+ my $status = shift || '' ;
+
+ $self->show_tickets(
+ sub {my $item = shift;
+ ( ( $item->prop('status') || '' ) eq $status )
+ ? 1
+ : 0;
+ }
+ );
+};
+
+
+
+template 'component' => page { 'Component: ' . ( $_[1] || 'none' ) }
content {
my $self = shift;
my $component = shift || '' ;
+
+
$self->show_tickets(
sub {my $item = shift;
( ( $item->prop('component') || '' ) eq $component && $item->has_active_status )
@@ -65,8 +137,7 @@ content {
);
};
-template 'no_milestone' => sub { show 'milestone' => undef };
-template 'milestone' => page { 'Milestone: ' . ( $_[1] || '<i>none</i>' ) }
+template 'milestone' => page { 'Milestone: ' . ( $_[1] || 'none' ) }
content {
my $self = shift;
my $milestone = shift;
@@ -83,6 +154,12 @@ content {
sub show_tickets {
my $self = shift;
+ my $tickets = $self->find_tickets(@_);
+ show( '/ticket_list', $tickets );
+}
+
+sub find_tickets {
+ my $self = shift;
my $callback = shift;
my $tickets = App::SD::Collection::Ticket->new(
@@ -90,7 +167,7 @@ sub show_tickets {
handle => $self->app_handle->handle
);
$tickets->matching($callback);
- show( '/ticket_list', $tickets );
+ return $tickets;
}
template edit_ticket => page {
@@ -316,6 +393,7 @@ private template 'ticket_list' => sub {
my $self = shift;
my $tickets = shift;
my $id = substr(rand(10),2); # hack to get a unique id
+ div { { class is 'ticket-list'};
table {
{ class is 'tablesorter'; id is $id; };
thead {
@@ -343,7 +421,7 @@ private template 'ticket_list' => sub {
}
};
- };
+ }};
script {outs_raw(qq{
\$(document).ready(function() { \$("#@{[$id]}").tablesorter(); } );
}
diff --git a/share/web/static/css/main.css b/share/web/static/css/main.css
index cbede37..94bc007 100644
--- a/share/web/static/css/main.css
+++ b/share/web/static/css/main.css
@@ -642,3 +642,77 @@ table.tablesorter td.summary {
}
+.pagesection {
+ max-width: 130px;
+ }
+
+.pagesection .bar-wrapper {
+ background: #ccc;
+ height: 6px;
+ margin-top: 4px;
+ margin-bottom: 2px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+
+}
+
+.pagesection .bar {
+ height: 6px;
+ background: #900;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+
+
+ }
+
+.pagesection li {
+ font-size: 0.8em;
+}
+
+.pagesection li a {
+ color: #000;
+ padding-left: 0.1em;
+ text-decoration: none;
+ font-weight: bold;
+}
+
+
+
+div.overview {
+ position: absolute;
+ top: 80px;
+ left: 160px;
+ right: 20px;
+
+
+}
+
+
+div.overview h2 {
+ padding-bottom: 0;
+ font-weight: normal;
+ border-bottom: 1px solid #ddd;
+}
+
+.sidebar {
+ width: 120px;
+ border-right: 1px solid #ddd;
+ padding-right: 10px;
+}
+
+.sidebar h2 {
+ padding-left: 0;
+ font-size: 1.1em;
+ font-weight: normal;
+ border-bottom: 1px solid #ddd;
+ padding-bottom: 5px;
+ margin-bottom: 10px;
+ padding-top: 0.5em;
+}
+
+.sidebar .pagesection {
+ padding-bottom: 5px;
+
+ border-bottom: 1px solid #ddd;
+
+}
-----------------------------------------------------------------------
More information about the Bps-public-commit
mailing list