diff options
21 files changed, 0 insertions, 1802 deletions
diff --git a/extensions/ProductDashboard/Config.pm b/extensions/ProductDashboard/Config.pm deleted file mode 100644 index 88ccdc784..000000000 --- a/extensions/ProductDashboard/Config.pm +++ /dev/null @@ -1,16 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Extension::ProductDashboard; - -use 5.10.1; -use strict; -use warnings; - -use constant NAME => 'ProductDashboard'; - -__PACKAGE__->NAME; diff --git a/extensions/ProductDashboard/Extension.pm b/extensions/ProductDashboard/Extension.pm deleted file mode 100644 index 18157c1fe..000000000 --- a/extensions/ProductDashboard/Extension.pm +++ /dev/null @@ -1,196 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. - -package Bugzilla::Extension::ProductDashboard; - -use 5.10.1; -use strict; -use warnings; - -use base qw(Bugzilla::Extension); - -use Bugzilla; -use Bugzilla::Constants; -use Bugzilla::Util; -use Bugzilla::Error; -use Bugzilla::Product; -use Bugzilla::Field; - -use Bugzilla::Extension::ProductDashboard::Queries; -use Bugzilla::Extension::ProductDashboard::Util; - -our $VERSION = BUGZILLA_VERSION; - -sub page_before_template { - my ($self, $args) = @_; - - my $page = $args->{page_id}; - my $vars = $args->{vars}; - - if ($page =~ m{^productdashboard\.}) { - _page_dashboard($vars); - } -} - -sub _page_dashboard { - my $vars = shift; - - my $cgi = Bugzilla->cgi; - my $input = Bugzilla->input_params; - my $user = Bugzilla->user; - - # Switch to shadow db since we are just reading information - Bugzilla->switch_to_shadow_db(); - - # Forget any previously selected product - $cgi->send_cookie(-name => 'PRODUCT_DASHBOARD', - -value => 'X', - -expires => "Fri, 01-Jan-1970 00:00:00 GMT"); - - # If the user cannot enter bugs in any product, stop here. - scalar @{$user->get_selectable_products} - || ThrowUserError('no_products'); - - # Create data structures representing each classification - my @classifications = (); - foreach my $c (@{$user->get_selectable_classifications}) { - # Create hash to hold attributes for each classification. - my %classification = ( - 'name' => $c->name, - 'products' => [ @{$user->get_selectable_products($c->id)} ] - ); - # Assign hash back to classification array. - push @classifications, \%classification; - } - $vars->{'classifications'} = \@classifications; - - my $product_name = trim($input->{'product'} || ''); - - if (!$product_name && $cgi->cookie('PRODUCT_DASHBOARD')) { - $product_name = $cgi->cookie('PRODUCT_DASHBOARD'); - } - - return if !$product_name; - - # We need to check and make sure that the user has permission - # to see this product. - my $product = Bugzilla::Product->new({ name => $product_name, cache => 1 }); - if (!$product || !$user->can_see_product($product->name)) { - return; - } - - # Remember selected product - $cgi->send_cookie(-name => 'PRODUCT_DASHBOARD', - -value => $product->name, - -expires => "Fri, 01-Jan-2038 00:00:00 GMT"); - - my $current_tab_name = $input->{'tab'} || "summary"; - trick_taint($current_tab_name); - $vars->{'current_tab_name'} = $current_tab_name; - - my $bug_status = trim($input->{'bug_status'} || 'open'); - - $vars->{'bug_status'} = $bug_status; - $vars->{'product'} = $product; - $vars->{'bug_link_all'} = bug_link_all($product); - $vars->{'bug_link_open'} = bug_link_open($product); - $vars->{'bug_link_closed'} = bug_link_closed($product); - $vars->{'total_bugs'} = total_bugs($product); - $vars->{'total_open_bugs'} = total_open_bugs($product); - $vars->{'total_closed_bugs'} = total_closed_bugs($product); - $vars->{'severities'} = get_legal_field_values('bug_severity'); - - if ($vars->{'total_bugs'}) { - $vars->{'open_bugs_percentage'} - = int($vars->{'total_open_bugs'} / $vars->{'total_bugs'} * 100); - $vars->{'closed_bugs_percentage'} - = int($vars->{'total_closed_bugs'} / $vars->{'total_bugs'} * 100); - } - else { - $vars->{'open_bugs_percentage'} = 0; - $vars->{'closed_bugs_percentage'} = 0; - } - - if ($current_tab_name eq 'summary') { - $vars->{'by_priority'} = by_priority($product, $bug_status); - $vars->{'by_severity'} = by_severity($product, $bug_status); - $vars->{'by_assignee'} = by_assignee($product, $bug_status, 50); - $vars->{'by_status'} = by_status($product, $bug_status); - } - - if ($current_tab_name eq 'recents') { - my $recent_days = $input->{'recent_days'} || 7; - (detaint_natural($recent_days) && $recent_days > 0 && $recent_days < 101) - || ThrowUserError('product_dashboard_invalid_recent_days'); - - my $params = { - product => $product, - days => $recent_days, - date_from => $input->{'date_from'} || '', - date_to => $input->{'date_to'} || '', - }; - - $vars->{'recently_opened'} = recently_opened($params); - $vars->{'recently_closed'} = recently_closed($params); - $vars->{'recent_days'} = $recent_days; - $vars->{'date_from'} = $input->{'date_from'}; - $vars->{'date_to'} = $input->{'date_to'}; - } - - if ($current_tab_name eq 'components') { - if ($input->{'component'}) { - $vars->{'summary'} = by_value_summary($product, 'component', $input->{'component'}, $bug_status); - $vars->{'summary'}{'type'} = 'component'; - $vars->{'summary'}{'value'} = $input->{'component'}; - } - elsif ($input->{'version'}) { - $vars->{'summary'} = by_value_summary($product, 'version', $input->{'version'}, $bug_status); - $vars->{'summary'}{'type'} = 'version'; - $vars->{'summary'}{'value'} = $input->{'version'}; - } - elsif ($input->{'target_milestone'} && Bugzilla->params->{'usetargetmilestone'}) { - $vars->{'summary'} = by_value_summary($product, 'target_milestone', $input->{'target_milestone'}, $bug_status); - $vars->{'summary'}{'type'} = 'target_milestone'; - $vars->{'summary'}{'value'} = $input->{'target_milestone'}; - } - else { - $vars->{'by_component'} = by_component($product, $bug_status); - $vars->{'by_version'} = by_version($product, $bug_status); - if (Bugzilla->params->{'usetargetmilestone'}) { - $vars->{'by_milestone'} = by_milestone($product, $bug_status); - } - } - } - - if ($current_tab_name eq 'duplicates') { - $vars->{'by_duplicate'} = by_duplicate($product, $bug_status); - } - - if ($current_tab_name eq 'popularity') { - $vars->{'by_popularity'} = by_popularity($product, $bug_status); - } - - if ($current_tab_name eq 'roadmap') { - foreach my $milestone (@{$product->milestones}){ - my %milestone_stats; - $milestone_stats{'name'} = $milestone->name; - $milestone_stats{'total_bugs'} = total_bug_milestone($product, $milestone); - $milestone_stats{'open_bugs'} = bug_milestone_by_status($product, $milestone, 'open'); - $milestone_stats{'closed_bugs'} = bug_milestone_by_status($product, $milestone, 'closed'); - $milestone_stats{'link_total'} = bug_milestone_link_total($product, $milestone); - $milestone_stats{'link_open'} = bug_milestone_link_open($product, $milestone); - $milestone_stats{'link_closed'} = bug_milestone_link_closed($product, $milestone); - $milestone_stats{'percentage'} = $milestone_stats{'total_bugs'} - ? int(($milestone_stats{'closed_bugs'} / $milestone_stats{'total_bugs'}) * 100) - : 0; - push (@{$vars->{'by_roadmap'}}, \%milestone_stats); - } - } -} - -__PACKAGE__->NAME; - diff --git a/extensions/ProductDashboard/lib/Queries.pm b/extensions/ProductDashboard/lib/Queries.pm deleted file mode 100644 index c5ed55b18..000000000 --- a/extensions/ProductDashboard/lib/Queries.pm +++ /dev/null @@ -1,478 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. -package Bugzilla::Extension::ProductDashboard::Queries; - -use 5.10.1; -use strict; -use warnings; - -use base qw(Exporter); -@Bugzilla::Extension::ProductDashboard::Queries::EXPORT = qw( - total_bugs - total_open_bugs - total_closed_bugs - by_version - by_value_summary - by_milestone - by_priority - by_severity - by_component - by_assignee - by_status - by_duplicate - by_popularity - recently_opened - recently_closed - total_bug_milestone - bug_milestone_by_status -); - -use Bugzilla::CGI; -use Bugzilla::Error; -use Bugzilla::User; -use Bugzilla::Util; -use Bugzilla::Component; -use Bugzilla::Version; -use Bugzilla::Milestone; - -use Bugzilla::Extension::ProductDashboard::Util qw(open_states closed_states - quoted_open_states quoted_closed_states); - -sub total_bugs { - my $product = shift; - my $dbh = Bugzilla->dbh; - - return $dbh->selectrow_array("SELECT COUNT(bug_id) - FROM bugs - WHERE product_id = ?", undef, $product->id); -} - -sub total_open_bugs { - my $product = shift; - my $bug_status = shift; - my $dbh = Bugzilla->dbh; - - return $dbh->selectrow_array("SELECT COUNT(bug_id) - FROM bugs - WHERE bug_status IN (" . join(',', quoted_open_states()) . ") - AND product_id = ?", undef, $product->id); -} - -sub total_closed_bugs { - my $product = shift; - my $dbh = Bugzilla->dbh; - - return $dbh->selectrow_array("SELECT COUNT(bug_id) - FROM bugs - WHERE bug_status IN (" . join(',', quoted_closed_states()) . ") - AND product_id = ?", undef, $product->id); -} - -sub bug_link_all { - my $product = shift; - - return correct_urlbase() . 'buglist.cgi?product=' . url_quote($product->name); -} - -sub bug_link_open { - my $product = shift; - - return correct_urlbase() . 'buglist.cgi?product=' . url_quote($product->name) . "&bug_status=__open__"; -} - -sub bug_link_closed { - my $product = shift; - - return correct_urlbase() . 'buglist.cgi?product=' . url_quote($product->name) . "&bug_status=__closed__"; -} - -sub by_version { - my ($product, $bug_status) = @_; - my $dbh = Bugzilla->dbh; - my $extra = ''; - - $extra = "AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ")" if $bug_status eq 'open'; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ")" if $bug_status eq 'closed'; - - return $dbh->selectall_arrayref("SELECT version, COUNT(bug_id), - ROUND(((COUNT(bugs.bug_id) / ( SELECT COUNT(*) FROM bugs WHERE bugs.product_id = ? $extra)) * 100)) - FROM bugs - WHERE product_id = ? - $extra - GROUP BY version - ORDER BY COUNT(bug_id) DESC", - undef, $product->id, $product->id); -} - -sub by_milestone { - my ($product, $bug_status) = @_; - my $dbh = Bugzilla->dbh; - my $extra = ''; - - $extra = "AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ")" if $bug_status eq 'open'; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ")" if $bug_status eq 'closed'; - - return $dbh->selectall_arrayref("SELECT target_milestone, COUNT(bug_id), - ROUND(((COUNT(bugs.bug_id) / ( SELECT COUNT(*) FROM bugs WHERE bugs.product_id = ? $extra)) * 100)) - FROM bugs - WHERE product_id = ? - $extra - GROUP BY target_milestone - ORDER BY COUNT(bug_id) DESC", - undef, $product->id, $product->id); -} - -sub by_priority { - my ($product, $bug_status) = @_; - my $dbh = Bugzilla->dbh; - my $extra = ''; - - $extra = "AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ")" if $bug_status eq 'open'; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ")" if $bug_status eq 'closed'; - - return $dbh->selectall_arrayref("SELECT priority, COUNT(bug_id), - ROUND(((COUNT(bugs.bug_id) / ( SELECT COUNT(*) FROM bugs WHERE bugs.product_id = ? $extra)) * 100)) - FROM bugs - WHERE product_id = ? - $extra - GROUP BY priority - ORDER BY COUNT(bug_id) DESC", - undef, $product->id, $product->id); -} - -sub by_severity { - my ($product, $bug_status) = @_; - my $dbh = Bugzilla->dbh; - my $extra = ''; - - $extra = "AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ")" if $bug_status eq 'open'; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ")" if $bug_status eq 'closed'; - - return $dbh->selectall_arrayref("SELECT bug_severity, COUNT(bug_id), - ROUND(((COUNT(bugs.bug_id) / ( SELECT COUNT(*) FROM bugs WHERE bugs.product_id = ? $extra)) * 100)) - FROM bugs - WHERE product_id = ? - $extra - GROUP BY bug_severity - ORDER BY COUNT(bug_id) DESC", - undef, $product->id, $product->id); -} - -sub by_component { - my ($product, $bug_status) = @_; - my $dbh = Bugzilla->dbh; - my $extra = ''; - - $extra = "AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ")" if $bug_status eq 'open'; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ")" if $bug_status eq 'closed'; - - return $dbh->selectall_arrayref("SELECT components.name, COUNT(bugs.bug_id), - ROUND(((COUNT(bugs.bug_id) / ( SELECT COUNT(*) FROM bugs WHERE bugs.product_id = ? $extra)) * 100)) - FROM bugs INNER JOIN components ON bugs.component_id = components.id - WHERE bugs.product_id = ? - $extra - GROUP BY components.name - ORDER BY COUNT(bugs.bug_id) DESC", - undef, $product->id, $product->id); -} - -sub by_value_summary { - my ($product, $type, $value, $bug_status) = @_; - my $dbh = Bugzilla->dbh; - - my $query = "SELECT bugs.bug_id AS id, - bugs.bug_status AS status, - bugs.version AS version, - components.name AS component, - bugs.bug_severity AS severity, - bugs.short_desc AS summary - FROM bugs, components - WHERE bugs.product_id = ? - AND bugs.component_id = components.id "; - - if ($type eq 'component') { - Bugzilla::Component->check({ product => $product, name => $value }); - $query .= "AND components.name = ? " if $type eq 'component'; - } - elsif ($type eq 'version') { - Bugzilla::Version->check({ product => $product, name => $value }); - $query .= "AND bugs.version = ? " if $type eq 'version'; - } - elsif ($type eq 'target_milestone') { - Bugzilla::Milestone->check({ product => $product, name => $value }); - $query .= "AND bugs.target_milestone = ? " if $type eq 'target_milestone'; - } - - $query .= "AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ") " if $bug_status eq 'open'; - $query .= "AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ") " if $bug_status eq 'closed'; - - trick_taint($value); - - my $past_due_bugs = $dbh->selectall_arrayref($query . - "AND (bugs.deadline IS NOT NULL AND bugs.deadline != '') - AND bugs.deadline < now() ORDER BY bugs.deadline LIMIT 10", - {'Slice' => {}}, $product->id, $value); - - my $updated_recently_bugs = $dbh->selectall_arrayref($query . - "AND bugs.delta_ts != bugs.creation_ts " . - "ORDER BY bugs.delta_ts DESC LIMIT 10", - {'Slice' => {}}, $product->id, $value); - - my $timestamp = $dbh->selectrow_array("SELECT " . $dbh->sql_date_format("LOCALTIMESTAMP(0)", "%Y-%m-%d")); - - return { - timestamp => $timestamp, - past_due => _filter_bugs($past_due_bugs), - updated_recently => _filter_bugs($updated_recently_bugs), - }; -} - -sub by_assignee { - my ($product, $bug_status, $limit) = @_; - my $dbh = Bugzilla->dbh; - my $extra = ''; - - $limit = ($limit && detaint_natural($limit)) ? $dbh->sql_limit($limit) : ""; - - $extra = "AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ")" if $bug_status eq 'open'; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ")" if $bug_status eq 'closed'; - - my @result = map { [ Bugzilla::User->new($_->[0]), $_->[1], $_->[2] ] } - @{$dbh->selectall_arrayref("SELECT bugs.assigned_to AS userid, COUNT(bugs.bug_id), - ROUND(((COUNT(bugs.bug_id) / ( SELECT COUNT(*) FROM bugs WHERE bugs.product_id = ? $extra)) * 100)) - FROM bugs, profiles - WHERE bugs.product_id = ? - AND bugs.assigned_to = profiles.userid - $extra - GROUP BY profiles.login_name - ORDER BY COUNT(bugs.bug_id) DESC $limit", - undef, $product->id, $product->id)}; - - return \@result; -} - -sub by_status { - my ($product, $bug_status) = @_; - my $dbh = Bugzilla->dbh; - my $extra = ''; - - $extra = "AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ")" if $bug_status eq 'open'; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ")" if $bug_status eq 'closed'; - - return $dbh->selectall_arrayref("SELECT bugs.bug_status, COUNT(bugs.bug_id), - ROUND(((COUNT(bugs.bug_id) / ( SELECT COUNT(*) FROM bugs WHERE bugs.product_id = ? $extra)) * 100)) - FROM bugs - WHERE bugs.product_id = ? - $extra - GROUP BY bugs.bug_status - ORDER BY COUNT(bugs.bug_id) DESC", - undef, $product->id, $product->id); -} - -sub total_bug_milestone { - my ($product, $milestone) = @_; - my $dbh = Bugzilla->dbh; - - return $dbh->selectrow_array("SELECT COUNT(bug_id) - FROM bugs - WHERE target_milestone = ? - AND product_id = ?", - undef, $milestone->name, $product->id); -} - -sub bug_milestone_by_status { - my ($product, $milestone, $bug_status) = @_; - my $dbh = Bugzilla->dbh; - my $extra = ''; - - $extra = "AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ")" if $bug_status eq 'open'; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ")" if $bug_status eq 'closed'; - - return $dbh->selectrow_array("SELECT COUNT(bug_id) - FROM bugs - WHERE target_milestone = ? - AND product_id = ? $extra", - undef, - $milestone->name, - $product->id); - -} - -sub by_duplicate { - my ($product, $bug_status, $limit) = @_; - my $dbh = Bugzilla->dbh; - $limit = ($limit && detaint_natural($limit)) ? $dbh->sql_limit($limit) : ""; - - my $extra = ''; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ")" if $bug_status eq 'open'; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ")" if $bug_status eq 'closed'; - - my $unfiltered_bugs = $dbh->selectall_arrayref("SELECT bugs.bug_id AS id, - bugs.bug_status AS status, - bugs.version AS version, - components.name AS component, - bugs.bug_severity AS severity, - bugs.short_desc AS summary, - COUNT(duplicates.dupe) AS dupe_count - FROM bugs, duplicates, components - WHERE bugs.product_id = ? - AND bugs.component_id = components.id - AND bugs.bug_id = duplicates.dupe_of - $extra - GROUP BY bugs.bug_id, bugs.bug_status, components.name, - bugs.bug_severity, bugs.short_desc - HAVING COUNT(duplicates.dupe) > 1 - ORDER BY COUNT(duplicates.dupe) DESC $limit", - {'Slice' => {}}, $product->id); - - return _filter_bugs($unfiltered_bugs); -} - -sub by_popularity { - my ($product, $bug_status, $limit) = @_; - my $dbh = Bugzilla->dbh; - $limit = ($limit && detaint_natural($limit)) ? $dbh->sql_limit($limit) : ""; - - my $extra = ''; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ")" if $bug_status eq 'open'; - $extra = "AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ")" if $bug_status eq 'closed'; - - my $unfiltered_bugs = $dbh->selectall_arrayref("SELECT bugs.bug_id AS id, - bugs.bug_status AS status, - bugs.version AS version, - components.name AS component, - bugs.bug_severity AS severity, - bugs.short_desc AS summary, - bugs.votes AS votes - FROM bugs, components - WHERE bugs.product_id = ? - AND bugs.component_id = components.id - AND bugs.votes > 1 - $extra - ORDER BY bugs.votes DESC $limit", - {'Slice' => {}}, $product->id); - - return _filter_bugs($unfiltered_bugs); -} - -sub recently_opened { - my ($params) = @_; - my $dbh = Bugzilla->dbh; - - my $product = $params->{'product'}; - my $days = $params->{'days'}; - my $limit = $params->{'limit'}; - my $date_from = $params->{'date_from'}; - my $date_to = $params->{'date_to'}; - - $days ||= 7; - $limit = ($limit && detaint_natural($limit)) ? $dbh->sql_limit($limit) : ""; - - my @values = ($product->id); - - my $date_part; - if ($date_from && $date_to) { - validate_date($date_from) - || ThrowUserError('illegal_date', { date => $date_from, - format => 'YYYY-MM-DD' }); - validate_date($date_to) - || ThrowUserError('illegal_date', { date => $date_to, - format => 'YYYY-MM-DD' }); - $date_part = "AND bugs.creation_ts >= ? AND bugs.creation_ts <= ?"; - push(@values, trick_taint($date_from), trick_taint($date_to)); - } - else { - $date_part = "AND bugs.creation_ts >= CURRENT_DATE() - INTERVAL ? DAY"; - push(@values, $days); - } - - my $unfiltered_bugs = $dbh->selectall_arrayref("SELECT bugs.bug_id AS id, - bugs.bug_status AS status, - bugs.version AS version, - components.name AS component, - bugs.bug_severity AS severity, - bugs.short_desc AS summary - FROM bugs, components - WHERE bugs.product_id = ? - AND bugs.component_id = components.id - AND bugs.bug_status IN (" . join(',', quoted_open_states()) . ") - $date_part - ORDER BY bugs.bug_id DESC $limit", - {'Slice' => {}}, @values); - - return _filter_bugs($unfiltered_bugs); -} - -sub recently_closed { - my ($params) = @_; - my $dbh = Bugzilla->dbh; - - my $product = $params->{'product'}; - my $days = $params->{'days'}; - my $limit = $params->{'limit'}; - my $date_from = $params->{'date_from'}; - my $date_to = $params->{'date_to'}; - - $days ||= 7; - $limit = ($limit && detaint_natural($limit)) ? $dbh->sql_limit($limit) : ""; - - my @values = ($product->id); - - my $date_part; - if ($date_from && $date_to) { - validate_date($date_from) - || ThrowUserError('illegal_date', { date => $date_from, - format => 'YYYY-MM-DD' }); - validate_date($date_to) - || ThrowUserError('illegal_date', { date => $date_to, - format => 'YYYY-MM-DD' }); - $date_part = "AND bugs_activity.bug_when >= ? AND bugs_activity.bug_when <= ?"; - push(@values, trick_taint($date_from), trick_taint($date_to)); - } - else { - $date_part = "AND bugs_activity.bug_when >= CURRENT_DATE() - INTERVAL ? DAY"; - push(@values, $days); - } - - my $unfiltered_bugs = $dbh->selectall_arrayref("SELECT DISTINCT bugs.bug_id AS id, - bugs.bug_status AS status, - bugs.version AS version, - components.name AS component, - bugs.bug_severity AS severity, - bugs.short_desc AS summary - FROM bugs, components, bugs_activity - WHERE bugs.product_id = ? - AND bugs.component_id = components.id - AND bugs.bug_status IN (" . join(',', quoted_closed_states()) . ") - AND bugs.bug_id = bugs_activity.bug_id - AND bugs_activity.added IN (" . join(',', quoted_closed_states()) . ") - $date_part - ORDER BY bugs.bug_id DESC $limit", - {'Slice' => {}}, @values); - - return _filter_bugs($unfiltered_bugs); -} - -sub _filter_bugs { - my ($unfiltered_bugs) = @_; - my $dbh = Bugzilla->dbh; - - return [] if !$unfiltered_bugs; - - my @unfiltered_bug_ids = map { $_->{'id'} } @$unfiltered_bugs; - my %filtered_bug_ids = map { $_ => 1 } @{ Bugzilla->user->visible_bugs(\@unfiltered_bug_ids) }; - - my @filtered_bugs; - foreach my $bug (@$unfiltered_bugs) { - next if !$filtered_bug_ids{$bug->{'id'}}; - push(@filtered_bugs, $bug); - } - - return \@filtered_bugs; -} - -1; diff --git a/extensions/ProductDashboard/lib/Util.pm b/extensions/ProductDashboard/lib/Util.pm deleted file mode 100644 index 651d76bf5..000000000 --- a/extensions/ProductDashboard/lib/Util.pm +++ /dev/null @@ -1,97 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# This Source Code Form is "Incompatible With Secondary Licenses", as -# defined by the Mozilla Public License, v. 2.0. -package Bugzilla::Extension::ProductDashboard::Util; - -use 5.10.1; -use strict; -use warnings; - -use base qw(Exporter); -@Bugzilla::Extension::ProductDashboard::Util::EXPORT = qw( - bug_link_all - bug_link_open - bug_link_closed - open_states - closed_states - quoted_open_states - quoted_closed_states - bug_milestone_link_total - bug_milestone_link_open - bug_milestone_link_closed -); - -use Bugzilla::Status; -use Bugzilla::Util; - -our $_open_states; -sub open_states { - $_open_states ||= Bugzilla::Status->match({ is_open => 1, isactive => 1 }); - return wantarray ? @$_open_states : $_open_states; -} - -our $_quoted_open_states; -sub quoted_open_states { - my $dbh = Bugzilla->dbh; - $_quoted_open_states ||= [ map { $dbh->quote($_->name) } open_states() ]; - return wantarray ? @$_quoted_open_states : $_quoted_open_states; -} - -our $_closed_states; -sub closed_states { - $_closed_states ||= Bugzilla::Status->match({ is_open => 0, isactive => 1 }); - return wantarray ? @$_closed_states : $_closed_states; -} - -our $_quoted_closed_states; -sub quoted_closed_states { - my $dbh = Bugzilla->dbh; - $_quoted_closed_states ||= [ map { $dbh->quote($_->name) } closed_states() ]; - return wantarray ? @$_quoted_closed_states : $_quoted_closed_states; -} - -sub bug_link_all { - my $product = shift; - - return correct_urlbase() . 'buglist.cgi?product=' . url_quote($product->name); -} - -sub bug_link_open { - my $product = shift; - - return correct_urlbase() . 'buglist.cgi?product=' . url_quote($product->name) . - "&bug_status=__open__"; -} - -sub bug_link_closed { - my $product = shift; - - return correct_urlbase() . 'buglist.cgi?product=' . url_quote($product->name) . - "&bug_status=__closed__"; -} - -sub bug_milestone_link_total { - my ($product, $milestone) = @_; - - return correct_urlbase() . 'buglist.cgi?product=' . url_quote($product->name) . - "&target_milestone=" . url_quote($milestone->name); -} - -sub bug_milestone_link_open { - my ($product, $milestone) = @_; - - return correct_urlbase() . 'buglist.cgi?product=' . url_quote($product->name) . - "&target_milestone=" . url_quote($milestone->name) . "&bug_status=__open__"; -} - -sub bug_milestone_link_closed { - my ($product, $milestone) = @_; - - return correct_urlbase() . 'buglist.cgi?product=' . url_quote($product->name) . - "&target_milestone=" . url_quote($milestone->name) . "&bug_status=__closed__"; -} - -1; diff --git a/extensions/ProductDashboard/template/en/default/hook/global/common-links-action-links.html.tmpl b/extensions/ProductDashboard/template/en/default/hook/global/common-links-action-links.html.tmpl deleted file mode 100644 index e9be8a13d..000000000 --- a/extensions/ProductDashboard/template/en/default/hook/global/common-links-action-links.html.tmpl +++ /dev/null @@ -1,9 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - - <li><span class="separator"> | </span><a href="page.cgi?id=productdashboard.html">Product Dashboard</a></li> diff --git a/extensions/ProductDashboard/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/ProductDashboard/template/en/default/hook/global/user-error-errors.html.tmpl deleted file mode 100644 index d8af64d31..000000000 --- a/extensions/ProductDashboard/template/en/default/hook/global/user-error-errors.html.tmpl +++ /dev/null @@ -1,12 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% IF error == "product_dashboard_invalid_recent_days" %] - [% title = "Invalid Recent Days" %] - Invalid value for recent days. -[% END %] diff --git a/extensions/ProductDashboard/template/en/default/pages/productdashboard.html.tmpl b/extensions/ProductDashboard/template/en/default/pages/productdashboard.html.tmpl deleted file mode 100644 index 413239b6c..000000000 --- a/extensions/ProductDashboard/template/en/default/pages/productdashboard.html.tmpl +++ /dev/null @@ -1,236 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% PROCESS global/variables.none.tmpl %] - -[% javascript_urls = [ "js/yui3.js", - "js/util.js", - "js/field.js" ] -%] - -[% IF current_tab_name == 'summary' %] - [% javascript_urls.push("extensions/ProductDashboard/web/js/summary.js") %] -[% ELSIF current_tab_name == 'recents' %] - [% javascript_urls.push("js/field.js") %] - [% javascript_urls.push("js/util.js") %] - [% javascript_urls.push("extensions/ProductDashboard/web/js/recents.js") %] -[% ELSIF current_tab_name == 'components' %] - [% javascript_urls.push("extensions/ProductDashboard/web/js/components.js") %] -[% ELSIF current_tab_name == 'duplicates' %] - [% javascript_urls.push("extensions/ProductDashboard/web/js/duplicates.js") %] -[% ELSIF current_tab_name == 'popularity' %] - [% javascript_urls.push("extensions/ProductDashboard/web/js/popularity.js") %] -[% ELSIF current_tab_name == 'roadmap' && Param('usetargetmilestone') %] - [% javascript_urls.push("extensions/ProductDashboard/web/js/roadmap.js") %] -[% END %] - -[% js = BLOCK %] - PD = {}; - [%# Set up severities list for proper sorting %] - PD.severities = new Array(); - [% sort_count = 0 %] - [% FOREACH s = severities %] - PD.severities['[% s FILTER js %]'] = [% sort_count FILTER js %]; - [% sort_count = sort_count + 1 %] - [% END %] -[% END %] - -[% filtered_product = product.name FILTER html %] -[% PROCESS global/header.html.tmpl - title = "Product Dashboard: $filtered_product" - generate_api_token = 1 - javascript = js - style_urls = [ "skins/yui3.css", - "skins/standard/buglist.css", - "extensions/ProductDashboard/web/styles/productdashboard.css" ] -%] - -[% url_filtered_product = product.name FILTER uri %] -[% url_filtered_status = bug_status FILTER uri %] - -[% tabs = [ - { - name => "summary", - label => "Summary", - link => "page.cgi?id=productdashboard.html&product=$url_filtered_product&bug_status=$url_filtered_status&tab=summary" - }, - { - name => "recents", - label => "Recents", - link => "page.cgi?id=productdashboard.html&product=$url_filtered_product&bug_status=$url_filtered_status&tab=recents" - }, - { - name => "components", - label => "Components/Versions", - link => "page.cgi?id=productdashboard.html&product=$url_filtered_product&bug_status=$url_filtered_status&tab=components" - }, - { - name => "duplicates", - label => "Duplicates", - link => "page.cgi?id=productdashboard.html&product=$url_filtered_product&bug_status=$url_filtered_status&tab=duplicates" - }, - { - name => "roadmap", - label => "Road Map", - link => "page.cgi?id=productdashboard.html&product=$url_filtered_product&bug_status=$url_filtered_status&tab=roadmap" - }, - ] -%] - -[% IF product.votesperuser %] - [% - tabs.push({ - name => "popularity", - label => "Popularity", - link => "page.cgi?id=productdashboard.html&product=$url_filtered_product&bug_status=$url_filtered_status&tab=popularity" - }) - %] -[% END %] - -[% FOREACH tab IN tabs %] - [% IF tab.name == current_tab_name %] - [% current_tab = tab %] - [% LAST %] - [% END %] -[% END %] - -[% full_bug_count = 0 %] -[% IF bug_status == 'open' %] - [% full_bug_count = total_open_bugs %] -[% ELSIF bug_status == 'closed' %] - [% full_bug_count = total_closed_bugs %] -[% ELSE %] - [% full_bug_count = total_bugs %] -[% END %] - -[% bug_link = bug_link_all %] -[% IF bug_status == 'open' %] - [% bug_link = bug_link_open %] -[% ELSIF bug_status == 'closed' %] - [% bug_link = bug_link_closed %] -[% END %] - -<div class="yui3-skin-sam"> - <a name="top"></a> - - <form action="page.cgi" method="get"> - <input type="hidden" name="id" value="productdashboard.html"> - <input type="hidden" name="tab" value="[% current_tab.name FILTER html %]"> - - [% IF summary.keys %] - <input type="hidden" name="[% summary.type FILTER html %]" value="[% summary.value FILTER html %]"> - [% END %] - - [% IF product %] - <span id="product_dashboard_links"> - <ul> - <li><a href="[% urlbase FILTER none %]enter_bug.cgi?product=[% product.name FILTER uri %]"> - Create a new [% terms.bug %] in this product</a></li> - <li><a href="[% urlbase FILTER none %]describecomponents.cgi?product=[% product.name FILTER uri %]"> - Show full component descriptions for this product</a></li> - </ul> - </span> - [% END %] - - <strong>Choose product:</strong> - <select name="product"> - [% FOREACH c = classifications %] - <optgroup label="[% c.name FILTER html %]"> - [% FOREACH p = c.products %] - <option value="[% p.name FILTER html %]" - [% IF p.name == product.name %]selected="selected"[% END %]> - [% p.name FILTER html %]</option> - [% END %]</optgroup> - [% END %] - </select> - <select name="bug_status" id="bug_status"> - [% statuses = [ { name = 'open', label = "Open $terms.Bugs" }, - { name = 'closed', label = "Closed $terms.Bugs" }, - { name = 'all', label = "All $terms.Bugs" } ] %] - [% FOREACH status = statuses %] - <option value="[% status.name FILTER html %]" - [% " selected" IF bug_status == "${status.name}" %]> - [% status.label FILTER html %] - </option> - [% END %] - </select> - - <input type="submit" value="[% IF product %]Change[% ELSE %]Submit[% END %]"> - - [% IF product %] - <div class="product_name"> - [% product.name FILTER html %] - </div> - - <div class="product_description"> - [% product.description FILTER none %] - </div> - - [% WRAPPER global/tabs.html.tmpl - tabs = tabs - current_tab = current_tab - %] - - [% IF current_tab.name == 'summary' %] - [% PROCESS pages/productdashboard/summary.html.tmpl %] - [% END %] - - [% IF current_tab.name == 'recents' %] - [% PROCESS pages/productdashboard/recents.html.tmpl %] - [% END %] - - [% IF current_tab.name == 'components' %] - [% PROCESS pages/productdashboard/components.html.tmpl %] - [% END %] - - [% IF current_tab.name == 'duplicates' %] - [% PROCESS pages/productdashboard/duplicates.html.tmpl %] - [% END %] - - [% IF current_tab.name == 'popularity' %] - [% PROCESS pages/productdashboard/popularity.html.tmpl %] - [% END %] - - [% IF current_tab.name == 'roadmap' && Param('usetargetmilestone') %] - [% PROCESS pages/productdashboard/roadmap.html.tmpl %] - [% END %] - - [% END %][%# END WRAPPER %] - [% END %] - - </form> -</div> - -[% PROCESS global/footer.html.tmpl %] - -[% BLOCK bar_graph %] - [% IF full_bug_count > 0 %][%# No divide by zero %] - [% percentage_bugs = (count / full_bug_count) * 100 FILTER format('%02.2f') %] - [% ELSE %] - [% percentage_bugs = 0 %] - [% END %] - <div class="bar_graph"> - <table cellpadding="0" cellspacing="0" width="300px"> - <tr> - <td width="[% percentage_bugs FILTER html %]%"> - <table cellpadding="0" cellspacing="0" width="100%"> - <tr> - <td bgcolor="#3c78b5"> - <a title="[% percentage_bugs FILTER html %]%"> - <img src="extensions/ProductDashboard/web/images/spacer.gif" height=10 width="100%" title="[% percentage_bugs FILTER html %]%"> - </a> - </td> - </tr> - </table> - </td> - <td width="[% 100 - percentage_bugs FILTER html %]%"> [% percentage_bugs FILTER html %]%</td> - </tr> - </table> - </div> -[% END %] - diff --git a/extensions/ProductDashboard/template/en/default/pages/productdashboard/components.html.tmpl b/extensions/ProductDashboard/template/en/default/pages/productdashboard/components.html.tmpl deleted file mode 100644 index d46fbc982..000000000 --- a/extensions/ProductDashboard/template/en/default/pages/productdashboard/components.html.tmpl +++ /dev/null @@ -1,146 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -[% IF summary.keys %] - -<h3>Summary for [% summary.type FILTER html %]: [% summary.value FILTER html %]</h3> - -<script> -<!-- - // Past due - [% IF user.is_timetracker %] - PD.past_due = [ - [% FOREACH bug = summary.past_due %] - { - id: [% bug.id FILTER js %], - bug_status: '[% bug.status FILTER js %]', - version: '[% bug.version FILTER js %]', - component: '[% bug.component FILTER js %]', - severity: '[% bug.severity FILTER js %]', - summary: '[% bug.summary FILTER js %]' - }, - [% END %] - ]; - [% END %] - - // Updated recently - PD.updated_recently = [ - [% FOREACH bug = summary.updated_recently %] - { - id: [% bug.id FILTER js %], - bug_status: '[% bug.status FILTER js %]', - version: '[% bug.version FILTER js %]', - component: '[% bug.component FILTER js %]', - severity: '[% bug.severity FILTER js %]', - summary: '[% bug.summary FILTER js %]' - }, - [% END %] - ]; ---> -</script> - -[% IF user.is_timetracker %] - <p> - <a href="#past_due">Past Due</a> | - <a href="#updated_recently">Updated Recently</a> - </p> -[% END %] - -<div class="yui3-skin-sam"> - - [% IF user.is_timetracker %] - <a name="past_due"></a> - <b>[% summary.past_due.size FILTER html %] Past Due [% terms.Bugs %]</b> (deadline is before today's date) - (<a href="[% bug_link FILTER html %]&[% summary.type FILTER uri %]=[% summary.value FILTER uri %]&field0-0-0=deadline&type0-0-0=lessthan&value0-0-0=[% summary.timestamp FILTER uri %]&order=deadline">full list</a>) - <div id="past_due"></div> - <br> - [% END %] - - <a name="updated_recently"></a> - <b>[% summary.updated_recently.size FILTER html %] Most Recently Updated [% terms.Bugs %]</b> - [% IF user.is_timetracker %](<a href="#top">back to top</a>)[% END %] - (<a href="[% bug_link FILTER html %]&[% summary.type FILTER uri %]=[% summary.value FILTER uri %]&order=changeddate DESC">full list</a>) - <div id="updated_recently"></div> -</div> - -[% ELSE %] - -<script type="text/javascript"> -<!-- - PD.product_name = '[% product.name FILTER js %]'; - PD.bug_status = '[% bug_status FILTER js %]'; - - // Component counts - PD.component_counts = [ - [% FOREACH col = by_component %] - { - name: "[% col.0 FILTER js %]", - count: [% col.1 || 0 FILTER js %], - percentage: [% col.2 || 0 FILTER js %], - link: '<a href="[% bug_link FILTER html %]&component=[% col.0 FILTER uri %]">Link</a>' - }, - [% END %] - ]; - - // Version counts - PD.version_counts = [ - [% FOREACH col = by_version %] - { - name: "[% col.0 FILTER js %]", - count: [% col.1 || 0 FILTER js %], - percentage: [% col.2 || 0 FILTER js %], - link: '<a href="[% bug_link FILTER html %]&version=[% col.0 FILTER uri %]">Link</a>' - }, - [% END %] - ]; - - [% IF Param('usetargetmilestone') %] - // Milestone counts - PD.milestone_counts = [ - [% FOREACH col = by_milestone %] - { - name: "[% col.0 FILTER js %]", - count: [% col.1 || 0 FILTER js %], - percentage: [% col.2 || 0 FILTER js %], - link: '<a href="[% bug_link FILTER html %]&target_milestone=[% col.0 FILTER uri %]">Link</a>' - }, - [% END %] - ]; - [% END %] ---> -</script> - -<h3>[% terms.Bug %] counts per component, version and milestone.</h3> - -<p> - <a href="#component">Component</a> | - <a href="#version">Version</a> | - <a href="#milestone">Milestone</a> -</p> - -<p>Click on a value to show a list of most recently updated [% terms.bugs %].</p> - -<div class="yui3-skin-sam"> - <a name="component"></a> - <b>Component</b> - <div id="component_counts"></div> - <br> - <a name="version"></a> - <b>Version</b> - (<a href="#top">back to top</a>) - <div id="version_counts"></div> - [% IF Param('usetargetmilestone') %] - <br> - <a name="milestone"></a> - <b>Milestone</b> - (<a href="#top">back to top</a>) - <div id="milestone_counts"></div> - [% END %] -</div> - -[% END %] diff --git a/extensions/ProductDashboard/template/en/default/pages/productdashboard/duplicates.html.tmpl b/extensions/ProductDashboard/template/en/default/pages/productdashboard/duplicates.html.tmpl deleted file mode 100644 index 8d9d240ed..000000000 --- a/extensions/ProductDashboard/template/en/default/pages/productdashboard/duplicates.html.tmpl +++ /dev/null @@ -1,34 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -<script type="text/javascript"> - PD.duplicates = [ - [% FOREACH bug = by_duplicate %] - { - id: [% bug.id FILTER js %], - count: [% bug.dupe_count FILTER js %], - status: '[% bug.status FILTER js %]', - version: '[% bug.version FILTER js %]', - component: '[% bug.component FILTER js %]', - severity: '[% bug.severity FILTER js %]', - summary: '[% bug.summary FILTER js %]' - }, - [% END %] - ]; -</script> - -<h3>Most duplicated [% terms.bugs %]</h3> - -[% IF by_duplicate.size %] - <b>[% by_duplicate.size FILTER html %] [% terms.Bugs %] Found</b> - <div class="yui3-skin-sam"> - <div id="duplicates"></div> - </div> -[% ELSE %] - <b>No duplicate [% terms.bugs %] found.</b> -[% END %] diff --git a/extensions/ProductDashboard/template/en/default/pages/productdashboard/popularity.html.tmpl b/extensions/ProductDashboard/template/en/default/pages/productdashboard/popularity.html.tmpl deleted file mode 100644 index dd895f078..000000000 --- a/extensions/ProductDashboard/template/en/default/pages/productdashboard/popularity.html.tmpl +++ /dev/null @@ -1,38 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -<style> - .yui-skin-sam .yui-dt table {width:100%;} -</style> - -<script type="text/javascript"> - PD.popularity = [ - [% FOREACH bug = by_popularity %] - { - id: [% bug.id FILTER js %], - count: [% bug.votes FILTER js %], - status: '[% bug.status FILTER js %]', - version: '[% bug.version FILTER js %]', - component: '[% bug.component FILTER js %]', - severity: '[% bug.severity FILTER js %]', - summary: '[% bug.summary FILTER js %]' - }, - [% END %] - ]; -</script> - -<h3>Most voted on [% terms.bugs %]</h3> - -[% IF by_popularity.size %] - <b>[% by_popularity.size FILTER html %] [% terms.Bugs %] Found</b> - <div class="yui3-skin-sam"> - <div id="popularity"></div> - </div> -[% ELSE %] - <b>No [% terms.bugs %] found.</b> -[% END %] diff --git a/extensions/ProductDashboard/template/en/default/pages/productdashboard/recents.html.tmpl b/extensions/ProductDashboard/template/en/default/pages/productdashboard/recents.html.tmpl deleted file mode 100644 index 0f4a2dcf2..000000000 --- a/extensions/ProductDashboard/template/en/default/pages/productdashboard/recents.html.tmpl +++ /dev/null @@ -1,87 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -<script type="text/javascript"> - PD.recents = {}; - - // Recently opened - PD.recents.opened = [ - [% FOREACH bug = recently_opened %] - { - id: [% bug.id FILTER js %], - status: '[% bug.status FILTER js %]', - version: '[% bug.version FILTER js %]', - component: '[% bug.component FILTER js %]', - severity: '[% bug.severity FILTER js %]', - summary: '[% bug.summary FILTER js %]' - }, - [% END %] - ]; - - // Recently closed - PD.recents.closed = [ - [% FOREACH bug = recently_closed %] - { - id: [% bug.id FILTER js %], - status: '[% bug.status FILTER js %]', - version: '[% bug.version FILTER js %]', - component: '[% bug.component FILTER js %]', - severity: '[% bug.severity FILTER js %]', - summary: '[% bug.summary FILTER js %]' - }, - [% END %] - ]; -</script> - -<h3>Most recently opened and closed [% terms.bugs %]</h3> - -<p> - Activity within the last <input type="text" size="4" name="recent_days" - value="[% recent_days FILTER html %]"> - days (between 1 and 100) or from - <input name="date_from" size="10" id="date_from" - value="[% date_from FILTER html %]" - onchange="updateCalendarFromField(this)"> - <button type="button" class="calendar_button" - id="button_calendar_date_from" - onclick="showCalendar('date_from')"> - <span>Calendar</span> - </button> - <span id="con_calendar_date_from"></span> - to - <input name="date_to" size="10" id="date_to" - value="[% date_to FILTER html %]" - onchange="updateCalendarFromField(this)"> - <button type="button" class="calendar_button" - id="button_calendar_date_to" - onclick="showCalendar('date_to')"> - <span>Calendar</span> - </button> - <span id="con_calendar_date_to"></span> - <script type="text/javascript"> - createCalendar('date_from') - createCalendar('date_to') - </script> - <input type="submit" name="change" value="Change"> -</p> -<p> - <a href="#recently_opened">Recently Opened</a> - <span class="separator"> | </span> - <a href="#recently_closed">Recently Closed</a> -</p> - -<div class="yui-skin-sam"> - <a name="recently_opened"></a> - <b>[% recently_opened.size FILTER html %] Recently Opened [% terms.Bugs %]</b> - <div id="recently_opened"></div> - <br> - <a name="recently_closed"></a> - <b>[% recently_closed.size FILTER html %] Recently Closed [% terms.Bugs %]</b> - (<a href="#top">back to top</a>) - <div id="recently_closed"></div> -</div> diff --git a/extensions/ProductDashboard/template/en/default/pages/productdashboard/roadmap.html.tmpl b/extensions/ProductDashboard/template/en/default/pages/productdashboard/roadmap.html.tmpl deleted file mode 100644 index b31827fbd..000000000 --- a/extensions/ProductDashboard/template/en/default/pages/productdashboard/roadmap.html.tmpl +++ /dev/null @@ -1,27 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -<script type="text/javascript"> -<!-- - PD.roadmap = [ - [% FOREACH milestone = by_roadmap %] - { - name: '[% milestone.name FILTER js %]', - percentage: '[% milestone.percentage FILTER js %]', - link: '<a href="[% milestone.link_closed FILTER html %]">[% milestone.closed_bugs FILTER html %]</a> of <a href="[% milestone.link_total FILTER html %]"> [% milestone.total_bugs FILTER html %]</a> [% terms.bugs %] have been closed', - }, - [% END %] - ]; ---> -</script> - -<h3>Percentage of [% terms.bug %] closure per milestone</h3> - -<div class="yui3-skin-sam"> - <div id="bug_milestones"></div> -</div> diff --git a/extensions/ProductDashboard/template/en/default/pages/productdashboard/summary.html.tmpl b/extensions/ProductDashboard/template/en/default/pages/productdashboard/summary.html.tmpl deleted file mode 100644 index 30b6f3dca..000000000 --- a/extensions/ProductDashboard/template/en/default/pages/productdashboard/summary.html.tmpl +++ /dev/null @@ -1,122 +0,0 @@ -[%# This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - # - # This Source Code Form is "Incompatible With Secondary Licenses", as - # defined by the Mozilla Public License, v. 2.0. - #%] - -<script> - PD.summary = {}; - - // global counts - PD.summary.bug_counts = [ - { - name: "Total [% terms.Bugs %]", - count: [% total_bugs || 0 FILTER js %], - percentage: [% total_bugs ? "100" : "0" %], - link: '<a href="[% bug_link_all FILTER js %]">Link</a>', - }, - { - name: "Open [% terms.Bugs %]", - count: [% total_open_bugs || 0 FILTER js %], - percentage: [% open_bugs_percentage FILTER js %], - link: '<a href="[% bug_link_open FILTER js %]">Link</a>', - }, - { - name: "Closed [% terms.Bugs %]", - count: [% total_closed_bugs || 0 FILTER js %], - percentage: [% closed_bugs_percentage FILTER js %], - link: '<a href="[% bug_link_closed FILTER js %]">Link</a>', - } - ]; - - // Status counts - PD.summary.status_counts = [ - [% FOREACH col = by_status %] - [% NEXT IF col.0 == 'CLOSED' %] - { - name: "[% col.0 FILTER js %]", - count: [% col.1 || 0 FILTER js %], - percentage: [% col.2 || 0 FILTER js %], - link: '<a href="[% bug_link_all FILTER js %]&bug_status=[% col.0 FILTER uri FILTER js %]">Link</a>' - }, - [% END %] - ]; - - // Priority counts - PD.summary.priority_counts = [ - [% FOREACH col = by_priority %] - { - name: "[% col.0 FILTER js %]", - count: [% col.1 || 0 FILTER js %], - percentage: [% col.2 || 0 FILTER js %], - link: '<a href="[% bug_link FILTER js %]&priority=[% col.0 FILTER uri FILTER js %]">Link</a>' - }, - [% END %] - ]; - - // Severity counts - PD.summary.severity_counts = [ - [% FOREACH col = by_severity %] - { - name: "[% col.0 FILTER js %]", - count: [% col.1 || 0 FILTER js %], - percentage: [% col.2 || 0 FILTER js %], - link: '<a href="[% bug_link FILTER js %]&bug_severity=[% col.0 FILTER uri FILTER js %]">Link</a>' - }, - [% END %] - ]; - - // Assignee counts - PD.summary.assignee_counts = [ - [% FOREACH col = by_assignee %] - { - name: "[% IF user.id %][% col.0.email FILTER js %][% ELSE %][% col.0.realname || 'No Name' FILTER js %][% END %]", - count: [% col.1 || 0 FILTER js %], - percentage: [% col.2 || 0 FILTER js %], - link: '[% IF user.id %]<a href="[% bug_link FILTER js %]&emailassigned_to1=1&emailtype1=exact&email1=[% col.0.email FILTER uri FILTER js %]">Link</a>[% END %]' - }, - [% END %] - ]; -</script> - -<h3>Summary of [% terms.bug %] counts</h3> - -<p> - <a href="#counts">Counts</a> - <span class="separator"> | </span> - <a href="#status">Status</a> - <span class="separator"> | </span> - <a href="#priority">Priority</a> - <span class="separator"> | </span> - <a href="#severity">Severity</a> - <span class="separator"> | </span> - <a href="#assignee">Assignee</a> -</p> - -<div class="yui3-skin-sam"> - <a name="counts"></a> - <b>[% terms.Bug %] Counts</b> - <div id="bug_counts"></div> - <br> - <a name="status"></a> - <b>Status</b> - (<a href="#top">back to top</a>) - <div id="status_counts"></div> - <br> - <a name="priority"></a> - <b>Priority</b> - (<a href="#top">back to top</a>) - <div id="priority_counts"></div> - <br> - <a name="severity"></a> - <b>Severity</b> - (<a href="#top">back to top</a>) - <div id="severity_counts"></div> - <br> - <a name="assignee"></a> - <b>Assignee</b> - (<a href="#top">back to top</a>) - <div id="assignee_counts"></div> -</div> diff --git a/extensions/ProductDashboard/web/images/spacer.gif b/extensions/ProductDashboard/web/images/spacer.gif Binary files differdeleted file mode 100644 index fc2560981..000000000 --- a/extensions/ProductDashboard/web/images/spacer.gif +++ /dev/null diff --git a/extensions/ProductDashboard/web/js/components.js b/extensions/ProductDashboard/web/js/components.js deleted file mode 100644 index 0c48576a7..000000000 --- a/extensions/ProductDashboard/web/js/components.js +++ /dev/null @@ -1,92 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This Source Code Form is "Incompatible With Secondary Licenses", as - * defined by the Mozilla Public License, v. 2.0. - */ - -$(function() { - YUI({ - base: 'js/yui3/', - combine: false - }).use("datatable", "datatable-sort", "escape", function(Y) { - if (typeof PD.updated_recently != 'undefined') { - var columns = [ - { key:"id", label:"ID", sortable:true, allowHTML: true, - formatter: '<a href="show_bug.cgi?id={value}" target="_blank">{value}</a>' }, - { key:"bug_status", label:"Status", sortable:true }, - { key:"version", label:"Version", sortable:true }, - { key:"component", label:"Component", sortable:true }, - { key:"severity", label:"Severity", sortable:true }, - { key:"summary", label:"Summary", sortable:false }, - ]; - - var updatedRecentlyDataTable = new Y.DataTable({ - columns: columns, - data: PD.updated_recently - }); - updatedRecentlyDataTable.render("#updated_recently"); - - if (typeof PD.past_due != 'undefined') { - var pastDueDataTable = new Y.DataTable({ - columns: columns, - data: PD.past_due - }); - pastDueDataTable.render('#past_due'); - } - } - - if (typeof PD.component_counts != 'undefined') { - var summary_url = '<a href="page.cgi?id=productdashboard.html&product=' + - encodeURIComponent(PD.product_name) + '&bug_status=' + - encodeURIComponent(PD.bug_status) + '&tab=components'; - - var columns = [ - { key:"name", label:"Name", sortable:true, allowHTML: true, - formatter: function (o) { - return summary_url + '&component=' + - encodeURIComponent(o.value) + '">' + - Y.Escape.html(o.value) + '</a>' - } - }, - { key:"count", label:"Count", sortable:true }, - { key:"percentage", label:"Percentage", sortable:false, allowHTML: true, - formatter: '<div class="percentage"><div class="bar" style="width:{value}%"></div><div class="percent">{value}%</div></div>' }, - { key:"link", label:"Link", sortable:false, allowHTML: true } - ]; - - var componentsDataTable = new Y.DataTable({ - columns: columns, - data: PD.component_counts - }); - componentsDataTable.render("#component_counts"); - - columns[0].formatter = function (o) { - return summary_url + '&version=' + - encodeURIComponent(o.value) + '">' + - Y.Escape.html(o.value) + '</a>'; - }; - - var versionsDataTable = new Y.DataTable({ - columns: columns, - data: PD.version_counts - }); - versionsDataTable.render('#version_counts'); - - if (typeof PD.milestone_counts != 'undefined') { - columns[0].formatter = function (o) { - return summary_url + '&target_milestone=' + - encodeURIComponent(o.value) + '">' + - Y.Escape.html(o.value) + '</a>'; - }; - - var milestonesDataTable = new Y.DataTable({ - columns: columns, - data: PD.milestone_counts - }); - milestonesDataTable.render('#milestone_counts'); - } - } - }); -}); diff --git a/extensions/ProductDashboard/web/js/duplicates.js b/extensions/ProductDashboard/web/js/duplicates.js deleted file mode 100644 index 57f890d6e..000000000 --- a/extensions/ProductDashboard/web/js/duplicates.js +++ /dev/null @@ -1,30 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This Source Code Form is "Incompatible With Secondary Licenses", as - * defined by the Mozilla Public License, v. 2.0. - */ - -$(function() { - YUI({ - base: 'js/yui3/', - combine: false - }).use("datatable", "datatable-sort", function (Y) { - var column_defs = [ - { key:"id", label:"ID", sortable:true, allowHTML: true, - formatter: '<a href="show_bug.cgi?id={value}" target="_blank">{value}</a>' }, - { key:"count", label:"Count", sortable:true }, - { key:"status", label:"Status", sortable:true }, - { key:"version", label:"Version", sortable:true }, - { key:"component", label:"Component", sortable:true }, - { key:"severity", label:"Severity", sortable:true }, - { key:"summary", label:"Summary", sortable:false }, - ]; - - var duplicatesDataTable = new Y.DataTable({ - columns: column_defs, - data: PD.duplicates - }).render('#duplicates'); - }); -}); diff --git a/extensions/ProductDashboard/web/js/popularity.js b/extensions/ProductDashboard/web/js/popularity.js deleted file mode 100644 index d496481fa..000000000 --- a/extensions/ProductDashboard/web/js/popularity.js +++ /dev/null @@ -1,30 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This Source Code Form is "Incompatible With Secondary Licenses", as - * defined by the Mozilla Public License, v. 2.0. - */ - -$(function() { - YUI({ - base: 'js/yui3/', - combine: false - }).use("datatable", "datatable-sort", function (Y) { - var column_defs = [ - { key:"id", label:"ID", sortable:true, allowHTML: true, - formatter: '<a href="show_bug.cgi?id={value}" target="_blank">{value}</a>' }, - { key:"count", label:"Count", sortable:true }, - { key:"status", label:"Status", sortable:true }, - { key:"version", label:"Version", sortable:true }, - { key:"component", label:"Component", sortable:true }, - { key:"severity", label:"Severity", sortable:true }, - { key:"summary", label:"Summary", sortable:false }, - ]; - - var popularityDataTable = new Y.DataTable({ - columns: column_defs, - data: PD.popularity - }).render('#popularity'); - }); -}); diff --git a/extensions/ProductDashboard/web/js/recents.js b/extensions/ProductDashboard/web/js/recents.js deleted file mode 100644 index d3a596c64..000000000 --- a/extensions/ProductDashboard/web/js/recents.js +++ /dev/null @@ -1,34 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This Source Code Form is "Incompatible With Secondary Licenses", as - * defined by the Mozilla Public License, v. 2.0. - */ - -$(function () { - YUI({ - base: 'js/yui3/', - combine: false - }).use("datatable", "datatable-sort", function (Y) { - var column_defs = [ - { key:"id", label:"ID", sortable:true, allowHTML: true, - formatter: '<a href="show_bug.cgi?id={value}" target="_blank">{value}</a>' }, - { key:"status", label:"Status", sortable:true }, - { key:"version", label:"Version", sortable:true }, - { key:"component", label:"Component", sortable:true }, - { key:"severity", label:"Severity", sortable:true }, - { key:"summary", label:"Summary", sortable:false }, - ]; - - var recentlyOpenedDataTable = new Y.DataTable({ - columns: column_defs, - data: PD.recents.opened - }).render('#recently_opened'); - - var recentlyClosedDataTable = new Y.DataTable({ - columns: column_defs, - data: PD.recents.closed - }).render('#recently_closed'); - }); -}); diff --git a/extensions/ProductDashboard/web/js/roadmap.js b/extensions/ProductDashboard/web/js/roadmap.js deleted file mode 100644 index 466446c13..000000000 --- a/extensions/ProductDashboard/web/js/roadmap.js +++ /dev/null @@ -1,26 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This Source Code Form is "Incompatible With Secondary Licenses", as - * defined by the Mozilla Public License, v. 2.0. - */ - -$(function() { - YUI({ - base: 'js/yui3/', - combine: false - }).use("datatable", "datatable-sort", function (Y) { - var column_defs = [ - { key: 'name', label: 'Name', sortable: true }, - { key: 'percentage', label: 'Percentage', sortable: false, allowHTML: true, - formatter: '<div class="percentage"><div class="bar" style="width:{value}%"></div><div class="percent">{value}%</div></div>' }, - { key: 'link', label: 'Links', allowHTML: true, sortable: false } - ]; - - var roadmapDataTable = new Y.DataTable({ - columns: column_defs, - data: PD.roadmap, - }).render('#bug_milestones'); - }); -}); diff --git a/extensions/ProductDashboard/web/js/summary.js b/extensions/ProductDashboard/web/js/summary.js deleted file mode 100644 index c4501200a..000000000 --- a/extensions/ProductDashboard/web/js/summary.js +++ /dev/null @@ -1,47 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This Source Code Form is "Incompatible With Secondary Licenses", as - * defined by the Mozilla Public License, v. 2.0. - */ - -$(function() { - YUI({ - base: 'js/yui3/', - combine: false - }).use("datatable", "datatable-sort", function (Y) { - var column_defs = [ - { key: 'name', label: 'Name', sortable: true }, - { key: 'count', label: 'Count', sortable: true }, - { key: 'percentage', label: 'Percentage', sortable: true, allowHTML: true, - formatter: '<div class="percentage"><div class="bar" style="width:{value}%"></div><div class="percent">{value}%</div></div>' }, - { key: 'link', label: 'Link', allowHTML: true } - ]; - - var bugsCountDataTable = new Y.DataTable({ - columns: column_defs, - data: PD.summary.bug_counts - }).render('#bug_counts'); - - var statusCountsDataTable = new Y.DataTable({ - columns: column_defs, - data: PD.summary.status_counts - }).render('#status_counts'); - - var priorityCountsDataTable = new Y.DataTable({ - columns: column_defs, - data: PD.summary.priority_counts - }).render('#priority_counts'); - - var severityCountsDataTable = new Y.DataTable({ - columns: column_defs, - data: PD.summary.severity_counts - }).render('#severity_counts'); - - var assigneeCountsDataTable = new Y.DataTable({ - columns: column_defs, - data: PD.summary.assignee_counts - }).render('#assignee_counts'); - }); -}); diff --git a/extensions/ProductDashboard/web/styles/productdashboard.css b/extensions/ProductDashboard/web/styles/productdashboard.css deleted file mode 100644 index c0c45cf38..000000000 --- a/extensions/ProductDashboard/web/styles/productdashboard.css +++ /dev/null @@ -1,45 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This Source Code Form is "Incompatible With Secondary Licenses", as - * defined by the Mozilla Public License, v. 2.0. */ - -#product_dashboard_links { - float: right; - padding-right: 25px; - border: 1px solid rgb(116, 126, 147); -} - -.product_name { - font-size: 2em; - margin: 10px 0 10px 0; - color: rgb(109, 117, 129); -} - -.product_description { - font-size: 90%; - font-style: italic; - padding-bottom: 5px; - margin-bottom: 10px; -} - -.percentage { - position:relative; - width: 200px; - border: 1px solid rgb(203, 203, 203); - position: relative; - padding: 3px; -} - -.bar{ - background-color: #00ff00; - height: 20px; -} - -.percent{ - position: absolute; - display: inline-block; - top: 3px; - left: 48%; -} |