diff options
author | Dave Arter <davea@mysociety.org> | 2017-12-05 12:38:36 +0000 |
---|---|---|
committer | Dave Arter <davea@mysociety.org> | 2017-12-05 12:38:36 +0000 |
commit | ff1fec27a51aa8c2f8ff6c74cc0a97d4739ba8ed (patch) | |
tree | b92c37a4d22ee1e3b431c203a8f552a4ba660f60 | |
parent | 6c2290663217efd2aab807448b321868866e0bc5 (diff) | |
parent | 509effcbcdf0f193c3dda787e7659b8ee6ea3ed1 (diff) |
Merge branch 'issues/forcouncils/40-open311-groups'
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/New.pm | 18 | ||||
-rw-r--r-- | perllib/Open311/PopulateServiceList.pm | 14 | ||||
-rw-r--r-- | t/open311/populate-service-list.t | 9 | ||||
-rw-r--r-- | templates/web/base/report/new/category.html | 33 | ||||
-rw-r--r-- | web/cobrands/fixmystreet/fixmystreet.js | 70 |
6 files changed, 134 insertions, 11 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index bfe8c04fc..7519434c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Add Expand map toggle to more mobile maps. - Add functionality to have per-body /reports page. - Cobrands can disable sending of moderation emails. #1910 + - Open311 category group support. #1923 - Front end improvements: - SVG assets for core elements like button icons and map controls #1888 - Remove unneeded 2x PNG fallback images. diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index 7f1de3ed4..f63b0af1e 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -664,7 +664,7 @@ sub setup_categories_and_bodies : Private { $bodies_to_list{ $contact->body_id } = $contact->body; unless ( $seen{$contact->category} ) { - push @category_options, { name => $contact->category, value => $contact->category_display }; + push @category_options, { name => $contact->category, value => $contact->category_display, group => $contact->get_extra_metadata('group') || '' }; my $metas = $contact->get_metadata_for_input; $category_extras{$contact->category} = $metas if @$metas; @@ -682,9 +682,9 @@ sub setup_categories_and_bodies : Private { if (@category_options) { # If there's an Other category present, put it at the bottom @category_options = ( - { name => _('-- Pick a category --'), value => _('-- Pick a category --') }, + { name => _('-- Pick a category --'), value => _('-- Pick a category --'), group => '' }, grep { $_->{name} ne _('Other') } @category_options ); - push @category_options, { name => _('Other'), value => $seen{_('Other')} } if $seen{_('Other')}; + push @category_options, { name => _('Other'), value => $seen{_('Other')}, group => _('Other') } if $seen{_('Other')}; } $c->cobrand->call_hook(munge_category_list => \@category_options, \@contacts, \%category_extras); @@ -705,6 +705,18 @@ sub setup_categories_and_bodies : Private { $c->stash->{missing_details_bodies} = \@missing_details_bodies; $c->stash->{missing_details_body_names} = \@missing_details_body_names; + + my %category_groups = (); + for my $category (@category_options) { + push @{$category_groups{$category->{group}}}, $category; + } + + my @category_groups = (); + for my $group ( grep { $_ ne _('Other') } sort keys %category_groups ) { + push @category_groups, { name => $group, categories => $category_groups{$group} }; + } + push @category_groups, { name => _('Other'), categories => $category_groups{_('Other')} } if ($category_groups{_('Other')}); + $c->stash->{category_groups} = \@category_groups; } sub setup_report_extra_fields : Private { diff --git a/perllib/Open311/PopulateServiceList.pm b/perllib/Open311/PopulateServiceList.pm index dbd0d1c68..e8d06efdf 100644 --- a/perllib/Open311/PopulateServiceList.pm +++ b/perllib/Open311/PopulateServiceList.pm @@ -156,7 +156,13 @@ sub _handle_existing_contact { if ( $contact and lc($metadata) eq 'true' ) { $self->_add_meta_to_contact( $contact ); } elsif ( $contact and $contact->extra and lc($metadata) eq 'false' ) { - $contact->update( { extra => undef } ); + $contact->set_extra_fields(); + $contact->update; + } + + if (my $group = $self->_current_service->{group}) { + $contact->set_extra_metadata(group => $group); + $contact->update; } push @{ $self->found_contacts }, $self->_current_service->{service_code}; @@ -182,6 +188,12 @@ sub _create_contact { ); }; + if (my $group = $self->_current_service->{group}) { + $contact->set_extra_metadata(group => $group); + $contact->update; + } + + if ( $@ ) { warn "Failed to create contact for service code " . $self->_current_service->{service_code} . " for body @{[$self->_current_body->id]}: $@\n" if $self->verbose >= 1; diff --git a/t/open311/populate-service-list.t b/t/open311/populate-service-list.t index 04740a9e8..7d4f491c6 100644 --- a/t/open311/populate-service-list.t +++ b/t/open311/populate-service-list.t @@ -39,6 +39,15 @@ subtest 'check basic functionality' => sub { my $contact_count = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1 } )->count(); is $contact_count, 3, 'correct number of contacts'; + + for my $test ( + { code => "001", group => "sanitation" }, + { code => "002", group => "street" }, + { code => "003", group => "street" }, + ) { + my $contact = FixMyStreet::DB->resultset('Contact')->search( { body_id => 1, email => $test->{code} } )->first; + is $contact->get_extra->{group}, $test->{group}, "Group set correctly"; + } }; subtest 'check non open311 contacts marked as deleted' => sub { diff --git a/templates/web/base/report/new/category.html b/templates/web/base/report/new/category.html index 16f6113f2..94d5479a6 100644 --- a/templates/web/base/report/new/category.html +++ b/templates/web/base/report/new/category.html @@ -1,19 +1,38 @@ -[% IF category_options.size ~%] +[% IF category_options.size OR category_groups.size ~%] + [%~ BLOCK category_option ~%] + [% cat_op_lc = cat_op.name | lower =%] + <option value='[% cat_op.name | html %]'[% ' selected' IF report.category == cat_op.name || category_lc == cat_op_lc || (category_options.size == 2 AND loop.last) ~%] + >[% IF loop.first %][% cat_op.value %][% ELSE %][% cat_op.value | html %][% END %]</option> + [%~ END ~%] + [% IF category; category_lc = category | lower; END; ~%] <label for='form_category' id="form_category_label"> [%~ loc('Category') ~%] </label>[% =%] - <select class="form-control" name="category" id="form_category" + <select class="form-control[% IF category_groups.size %] js-grouped-select[% END %]" name="category" id="form_category" [%~ IF c.user.from_body =%] data-role="[% c.user.has_body_permission_to('planned_reports') ? 'inspector' : 'user' %]" data-body="[% c.user.from_body.name %]" data-prefill="[% c.cobrand.prefill_report_fields_for_inspector %]" [%~ END ~%] > - [%~ FOREACH cat_op IN category_options ~%] - [% cat_op_lc = cat_op.name | lower =%] - <option value='[% cat_op.name | html %]'[% ' selected' IF report.category == cat_op.name || category_lc == cat_op_lc || (category_options.size == 2 AND loop.last) ~%] - >[% IF loop.first %][% cat_op.value %][% ELSE %][% cat_op.value | html %][% END %]</option> - [%~ END =%] + [%~ IF category_groups.size ~%] + [%~ FOREACH group IN category_groups ~%] + [% IF group.name %]<optgroup label="[% group.name %]">[% END %] + [%~ FOREACH cat_op IN group.categories ~%] + [% INCLUDE category_option %] + [%~ END ~%] + [% IF group.name %]</optgroup>[% END %] + [%~ END =%] + [%~ ELSE ~%] + [%~ FOREACH cat_op IN category_options ~%] + [% INCLUDE category_option %] + [%~ END =%] + [%~ END ~%] </select> + [%~ IF category_groups.size ~%] + <label id="form_subcategory_label" class="hidden"> + [%~ loc('Subcategory') ~%] + </label> + [%~ END ~%] [%~ END ~%] diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js index 16ee7b511..d6ea9de18 100644 --- a/web/cobrands/fixmystreet/fixmystreet.js +++ b/web/cobrands/fixmystreet/fixmystreet.js @@ -424,6 +424,75 @@ $.extend(fixmystreet.set_up, { }); }, + category_groups: function() { + var $category_select = $("select#form_category.js-grouped-select"); + if ($category_select.length === 0) { + return; + } + var $group_select = $("<select></select>").addClass("form-control"); + var $subcategory_label = $("#form_subcategory_label"); + var $empty_option = $category_select.find("option").first(); + + $group_select.change(function() { + var subcategory_id = $(this).find(":selected").data("subcategory_id"); + $(".js-subcategory").hide(); + if (subcategory_id === undefined) { + $subcategory_label.addClass("hidden"); + $category_select.val($(this).val()).change(); + } else { + $("#" + subcategory_id).show().change(); + $("#form_subcategory_label").removeClass("hidden"); + } + }); + + var subcategory_change = function() { + $category_select.val($(this).val()).change(); + }; + + var add_optgroup = function(el) { + var $el = $(el); + var $options = $el.find("option"); + + if ($options.length == 1) { + add_option($options.get(0)); + } else { + var label = $el.attr("label"); + var subcategory_id = "subcategory_" + label.replace(/[^a-zA-Z]+/g, ''); + var $opt = $("<option></option>").text(label).val(label); + $opt.data("subcategory_id", subcategory_id); + $group_select.append($opt); + + var $sub_select = $("<select></select>").addClass("form-control js-subcategory"); + $sub_select.attr("id", subcategory_id); + $sub_select.append($empty_option.clone()); + $options.each(function() { + var $newopt = $(this).clone(); + $sub_select.append($newopt); + // Make sure any preselected value is preserved in the new UI: + if ($newopt.attr('selected')) { + $group_select.val(label); + } + }); + $sub_select.hide().insertAfter($subcategory_label).change(subcategory_change); + } + }; + + var add_option = function(el) { + $group_select.append($(el).clone()); + }; + + $category_select.hide(); + $group_select.insertAfter($category_select); + $category_select.find("optgroup, > option").each(function() { + if (this.tagName.toLowerCase() === 'optgroup') { + add_optgroup(this); + } else if (this.tagName.toLowerCase() === 'option') { + add_option(this); + } + }); + $group_select.change(); + }, + hide_name: function() { $('body').on('click', '.js-hide-name', function(e){ e.preventDefault(); @@ -862,6 +931,7 @@ fixmystreet.update_pin = function(lonlat, savePushState) { if (category_select.val() != '-- Pick a category --') { category_select.change(); } + fixmystreet.run(fixmystreet.set_up.category_groups); if (data.contribute_as) { var $select = $('.js-contribute-as'); |