Commit 48b0cf38 authored by lpsolit%gmail.com's avatar lpsolit%gmail.com

Bug 319067: editflagtypes.cgi should allow to filter flag types based on their…

Bug 319067: editflagtypes.cgi should allow to filter flag types based on their product/component - Patch by Frédéric Buclin <LpSolit@gmail.com> r=wicked a=myk
parent a59456eb
......@@ -42,6 +42,8 @@ use Bugzilla::Util;
use Bugzilla::Product;
use Bugzilla::Component;
use List::Util qw(reduce);
my $template = Bugzilla->template;
my $vars = {};
......@@ -92,13 +94,54 @@ exit;
################################################################################
sub list {
# Restrict the list to the given product and component, if given.
$vars = get_products_and_components($vars);
my $product = validateProduct(scalar $cgi->param('product'));
my $component = validateComponent($product, scalar $cgi->param('component'));
my $product_id = $product ? $product->id : 0;
my $component_id = $component ? $component->id : 0;
# Define the variables and functions that will be passed to the UI template.
$vars->{'bug_types'} =
Bugzilla::FlagType::match({ 'target_type' => 'bug',
'group' => scalar $cgi->param('group') }, 1);
$vars->{'attachment_types'} =
Bugzilla::FlagType::match({ 'target_type' => 'attachment',
'group' => scalar $cgi->param('group') }, 1);
$vars->{'selected_product'} = $cgi->param('product');
$vars->{'selected_component'} = $cgi->param('component');
# If only a product was specified but no component, then we restrict
# the list to flag types available in ALL components of that product.
my @comp_ids = ($component_id);
if ($product_id && !$component_id) {
@comp_ids = map {$_->id} @{$product->components};
}
my @bug_flagtypes;
my @attach_flagtypes;
foreach my $comp_id (@comp_ids) {
my $bug_types =
Bugzilla::FlagType::match({ 'target_type' => 'bug',
'group' => scalar $cgi->param('group'),
'product_id' => $product_id,
'component_id' => $comp_id }, 1);
push(@bug_flagtypes, $bug_types);
my $attach_types =
Bugzilla::FlagType::match({ 'target_type' => 'attachment',
'group' => scalar $cgi->param('group'),
'product_id' => $product_id,
'component_id' => $comp_id }, 1);
push(@attach_flagtypes, $attach_types);
}
sub intersection {
my ($aa, $bb) = @_;
my %union;
my %isect;
foreach my $e (@$aa, @$bb) { $union{$e->{'id'}}++ && ($isect{$e->{'id'}} ||= $e) };
return [sort { $a->{'sortkey'} <=> $b->{'sortkey'}
|| $a->{'name'} cmp $b->{'name'} } values %isect];
}
$vars->{'bug_types'} = reduce { intersection($a, $b) } @bug_flagtypes;
$vars->{'attachment_types'} = reduce { intersection($a, $b) } @attach_flagtypes;
# Users want to see group names, not IDs
# So get the group names
......@@ -127,16 +170,8 @@ sub edit {
$action eq 'enter' ? validateTargetType() : (my $id = validateID());
my $dbh = Bugzilla->dbh;
my @products = Bugzilla::Product::get_all_products();
# We require all unique component names.
my %components;
foreach my $product (@products) {
foreach my $component (@{$product->components}) {
$components{$component->name} = 1;
}
}
$vars->{'products'} = \@products;
$vars->{'components'} = [sort(keys %components)];
# Fill $vars with products and components data.
$vars = get_products_and_components($vars);
$vars->{'last_action'} = $cgi->param('action');
if ($cgi->param('action') eq 'enter' || $cgi->param('action') eq 'copy') {
......@@ -217,16 +252,8 @@ sub processCategoryChange {
my %inclusions = clusion_array_to_hash(\@inclusions);
my %exclusions = clusion_array_to_hash(\@exclusions);
my @products = Bugzilla::Product::get_all_products();
# We require all unique component names.
my %components;
foreach my $product (@products) {
foreach my $component (@{$product->components}) {
$components{$component->name} = 1;
}
}
$vars->{'products'} = \@products;
$vars->{'components'} = [sort(keys %components)];
# Fill $vars with products and components data.
$vars = get_products_and_components($vars);
my @groups = Bugzilla::Group::get_all_groups();
$vars->{'groups'} = \@groups;
......@@ -475,6 +502,21 @@ sub deactivate {
|| ThrowTemplateError($template->error());
}
sub get_products_and_components {
my $vars = shift;
my @products = Bugzilla::Product::get_all_products();
# We require all unique component names.
my %components;
foreach my $product (@products) {
foreach my $component (@{$product->components}) {
$components{$component->name} = 1;
}
}
$vars->{'products'} = \@products;
$vars->{'components'} = [sort(keys %components)];
return $vars;
}
################################################################################
# Data Validation / Security Authorization
......@@ -550,7 +592,7 @@ sub validateComponent {
return unless $component_name;
($product && $product->id)
|| ThrowCodeError("flag_type_component_without_product");
|| ThrowUserError("flag_type_component_without_product");
my $component = Bugzilla::Component::check_component($product, $component_name);
return $component;
......
......@@ -22,17 +22,7 @@
[% PROCESS global/variables.none.tmpl %]
[%# The javascript block gets used in header.html.tmpl. %]
[% javascript = BLOCK %]
var usetms = 0; // do we have target milestone?
var first_load = 1; // is this the first time we load the page?
var last_sel = []; // caches last selection
var cpts = new Array();
[% FOREACH prod = products %]
cpts['[% prod.name FILTER js %]'] = [
[%- FOREACH comp = prod.components %]'[% comp.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
[% END %]
[% END %]
[% PROCESS "global/js-products.html.tmpl" %]
[% IF type.target_type == "bug" %]
[% title = BLOCK %]Create Flag Type for [% terms.Bugs %][% END %]
......
......@@ -21,6 +21,8 @@
[% PROCESS global/variables.none.tmpl %]
[% PROCESS "global/js-products.html.tmpl" %]
[% PROCESS global/header.html.tmpl
title = 'Administer Flag Types'
style = "
......@@ -28,6 +30,8 @@
.inactive { color: #787878; }
.multiplicable { display: block; }
"
onload="selectProduct(document.forms[0], 'product', 'component', '__All__');"
javascript_urls=["productmenu.js"]
%]
<p>
......@@ -44,6 +48,42 @@
depending on whether the patch passed or failed review.
</p>
<p>
You can restrict the list of flag types to those available for a given product
and component. If a product is selected with no component, only flag types
which are available to ALL components of the product are shown.
</p>
<form action="editflagtypes.cgi" method="get">
<table>
<tr>
<th><label for="product">Product:</label></th>
<td>
<select name="product" onchange="selectProduct(this.form, 'product', 'component', '__All__');">
<option value="">__All__</option>
[% FOREACH prod = products %]
<option value="[% prod.name FILTER html %]"
[% " selected" IF selected_product == prod.name %]>
[% prod.name FILTER html %]</option>
[% END %]
</select>
</td>
<th><label for="component">Component:</label></th>
<td>
<select name="component">
<option value="">__All__</option>
[% FOREACH comp = components %]
<option value="[% comp FILTER html %]"
[% " selected" IF selected_component == comp %]>
[% comp FILTER html %]</option>
[% END %]
</select>
</td>
<td><input type="submit" id="submit" value="Filter"></td>
</tr>
</table>
</form>
<h3>Flag Types for [% terms.Bugs %]</h3>
[% PROCESS display_flag_types types=bug_types %]
......
......@@ -227,9 +227,6 @@
[% END %]
is invalid.
[% ELSIF error == "flag_type_component_without_product" %]
A component was selected without a product being selected.
[% ELSIF error == "flag_type_id_invalid" %]
The flag type ID <em>[% id FILTER html %]</em> is not
a positive integer.
......
[%# 1.0@bugzilla.org %]
[%# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Myk Melez <myk@mozilla.org>
# Frédéric Buclin <LpSolit@gmail.com>
#%]
[%# The javascript block gets used in header.html.tmpl. %]
[% javascript = BLOCK %]
var usetms = 0; // do we have target milestone?
var first_load = 1; // is this the first time we load the page?
var last_sel = []; // caches last selection
var cpts = new Array();
[% FOREACH prod = products %]
cpts['[% prod.name FILTER js %]'] = [
[%- FOREACH comp = prod.components %]'[% comp.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
[% END %]
[% END %]
......@@ -473,6 +473,10 @@
[% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %]
The CC list [% cc_list FILTER html %] must be less than 200 characters long.
[% ELSIF error == "flag_type_component_without_product" %]
[% title = "Product Missing" %]
A component was selected without a product being selected.
[% ELSIF error == "flag_type_description_invalid" %]
[% title = "Flag Type Description Invalid" %]
[% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %]
......
......@@ -24,17 +24,7 @@
[% USE Bugzilla %]
[% cgi = Bugzilla.cgi %]
[%# The javascript block gets used in header.html.tmpl. %]
[% javascript = BLOCK %]
var usetms = 0; // do we have target milestone?
var first_load = 1; // is this the first time we load the page?
var last_sel = []; // caches last selection
var cpts = new Array();
[% FOREACH prod = products %]
cpts['[% prod.name FILTER js %]'] = [
[%- FOREACH comp = prod.components %]'[% comp.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ];
[% END %]
[% END %]
[% PROCESS "global/js-products.html.tmpl" %]
[% PROCESS global/header.html.tmpl
title="Request Queue"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment