aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Arter <davea@mysociety.org>2017-12-05 12:38:36 +0000
committerDave Arter <davea@mysociety.org>2017-12-05 12:38:36 +0000
commitff1fec27a51aa8c2f8ff6c74cc0a97d4739ba8ed (patch)
treeb92c37a4d22ee1e3b431c203a8f552a4ba660f60
parent6c2290663217efd2aab807448b321868866e0bc5 (diff)
parent509effcbcdf0f193c3dda787e7659b8ee6ea3ed1 (diff)
Merge branch 'issues/forcouncils/40-open311-groups'
-rw-r--r--CHANGELOG.md1
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/New.pm18
-rw-r--r--perllib/Open311/PopulateServiceList.pm14
-rw-r--r--t/open311/populate-service-list.t9
-rw-r--r--templates/web/base/report/new/category.html33
-rw-r--r--web/cobrands/fixmystreet/fixmystreet.js70
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');