diff options
Diffstat (limited to 'extensions')
-rw-r--r-- | extensions/BugModal/lib/WebService.pm | 23 | ||||
-rw-r--r-- | extensions/BugModal/template/en/default/bug_modal/field.html.tmpl | 3 | ||||
-rw-r--r-- | extensions/BugModal/web/new_bug.js | 105 |
3 files changed, 89 insertions, 42 deletions
diff --git a/extensions/BugModal/lib/WebService.pm b/extensions/BugModal/lib/WebService.pm index 556a2d7cc..99d0383cc 100644 --- a/extensions/BugModal/lib/WebService.pm +++ b/extensions/BugModal/lib/WebService.pm @@ -38,9 +38,9 @@ sub rest_resources { # return all the components pertaining to the product. # required by new-bug - qr{^/bug_modal/components}, { + qr{^/bug_modal/product_info}, { GET => { - method => 'components', + method => 'product_info', params => sub { return { product_name => Bugzilla->input_params->{product} } }, @@ -87,19 +87,24 @@ sub products { return { products => _name($user->get_enterable_products) }; } -sub components { +sub product_info { my ( $self, $params ) = @_; if ( !ref $params->{product_name} ) { untaint( $params->{product_name} ); } else { - ThrowCodeError( 'params_required', - { function => 'BugModal.components', params => ['product'] } ); + ThrowCodeError( 'params_required', { function => 'BugModal.components', params => ['product'] } ); } - my $product = Bugzilla::Product->check({ name => $params->{product_name}, cache => 1 }); - $product = Bugzilla->user->can_enter_product($product, 1); - my @components = map { { name => $_->name, description => Bugzilla::Component->check({ product => $product, name => $_->name })->description} } @{ $product->components }; - return { components => \@components } + my $product = Bugzilla::Product->check( { name => $params->{product_name}, cache => 1 } ); + $product = Bugzilla->user->can_enter_product( $product, 1 ); + my @components = map { + { + name => $_->name, + description => $_->description, + } + } @{ $product->components }; + my @versions = map { { name => $_->name } } grep { $_->is_active } @{ $product->versions }; + return { components => \@components, versions => \@versions }; } # everything we need for edit mode in a single call, returning just the fields diff --git a/extensions/BugModal/template/en/default/bug_modal/field.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/field.html.tmpl index e84327307..c54f7c257 100644 --- a/extensions/BugModal/template/en/default/bug_modal/field.html.tmpl +++ b/extensions/BugModal/template/en/default/bug_modal/field.html.tmpl @@ -28,6 +28,7 @@ # edit html instead of replacing it. forces edit_only (default: false); # default: (string) default value (eg. used as a placeholder in user fields) # help: (string) optional url that describes the field (requires a label to be defined and visible) + # required: (boolean) if the field is required. (At present, only implemented for FIELD_TYPE_FREETEXT) # action: (hash) show a button to the right of the edit field (user fields only currently). keys: # id: (string) optional button id # class: (string) optional button class @@ -218,7 +219,7 @@ END; [% CASE constants.FIELD_TYPE_FREETEXT %] [%# normal input field %] - <input name="[% name FILTER html %]" id="[% name FILTER html %]" value="[% value FILTER html %]" [% aria_labelledby_html FILTER none %]> + <input name="[% name FILTER html %]" id="[% name FILTER html %]" value="[% value FILTER html %]" [% aria_labelledby_html FILTER none %] [% "required" IF required %]> [% CASE constants.FIELD_TYPE_USER %] [% IF action && !action.hidden %] <button class="field-button minor [%= action.class FILTER html IF action.class %]" diff --git a/extensions/BugModal/web/new_bug.js b/extensions/BugModal/web/new_bug.js index cd1b16453..cd471fc2e 100644 --- a/extensions/BugModal/web/new_bug.js +++ b/extensions/BugModal/web/new_bug.js @@ -1,48 +1,89 @@ -$(document).ready(function() { +var comp_desc = {} + +function load_products(query, callback) { bugzilla_ajax( { url: 'rest/bug_modal/products' }, function(data) { - $('#product').empty() - $('#product').append($('<option>', { value: 'Select Product', text: 'Select Product' })); - // populate select menus - $.each(data.products, function(key, value) { - $('#product').append($('<option>', { value: value.name, text: value.name })); - }); + callback(data.products); }, - function() {} + function() { + callback(); + } ); +} + +$(document).ready(function() { + var product_sel = $("#product").selectize({ + valueField: 'name', + labelField: 'name', + searchField: 'name', + options: [], + preload: true, + create: false, + load: load_products + }); + var component_sel = $("#component").selectize({ + valueField: 'name', + labelField: 'name', + searchField: 'name', + options: [], + }); - $('#component').empty() - $('#component').append($('<option>', { value: 'Select Component', text: 'Select Component' })); + var version_sel = $("#version").selectize({ + valueField: 'name', + labelField: 'name', + searchField: 'name', + options: [], + }); - $('#product') - .change(function(event) { + product_sel.on("change", function () { $('#product-throbber').show(); $('#component').attr('disabled', true); - $("#product option[value='Select Product']").remove(); bugzilla_ajax( - { - url: 'rest/bug_modal/components?product=' + encodeURIComponent($('#product').val()) - }, - function(data) { - $('#product-throbber').hide(); - $('#component').attr('disabled', false); - $('#component').empty(); - $('#component').append($('<option>', { value: 'Select Component', text: 'Select Component' })); - $('#comp_desc').text('Select a component to read its description.'); - $.each(data.components, function(key, value) { - $('#component').append('<option value=' + value.name + ' desc=' + value.description.split(' ').join('_') + '>' + value.name + '</option>'); - }); - }, - function() {} - ); + { + url: 'rest/bug_modal/product_info?product=' + encodeURIComponent($('#product').val()) + }, + function(data) { + product_info = data; + $('#product-throbber').hide(); + $('#component').attr('disabled', false); + $('#comp_desc').text('Select a component to read its description.'); + var selectize = $("#component")[0].selectize; + selectize.clear(); + selectize.clearOptions(); + selectize.load(function(callback) { + callback(data.components) + }); + + for (var i in data.components) + comp_desc[data.components[i]["name"]] = data.components[i]["description"]; + + selectize = $("#version")[0].selectize; + selectize.clear(); + selectize.clearOptions(); + selectize.load(function(callback) { + callback(data.versions); + }); + }, + function() { + alert("Network issues. Please refresh the page and try again"); + } + ); }); - $('#component') - .change(function(event) { - $("#component option[value='Select Product']").remove(); - $('#comp_desc').text($('#component').find(":selected").attr('desc').split('_').join(' ')); + + component_sel.on("change", function () { + var selectize = $("#component")[0].selectize; + $('#comp_desc').text(comp_desc[selectize.getValue()]); }); + + $('.create-btn') + .click(function(event) { + event.preventDefault(); + if (document.newbugform.checkValidity && !document.newbugform.checkValidity()) + return; + this.form.submit() + }); }); |