diff --git a/app/controllers/admin/neighbourhoods_controller.rb b/app/controllers/admin/neighbourhoods_controller.rb
index 596492864..e2b7790be 100644
--- a/app/controllers/admin/neighbourhoods_controller.rb
+++ b/app/controllers/admin/neighbourhoods_controller.rb
@@ -10,9 +10,10 @@ def index
respond_to do |format|
format.html
format.json { render json: NeighbourhoodDatatable.new(
- params, view_context: view_context,
+ params,
+ view_context: view_context,
neighbourhoods: @neighbourhoods
- )
+ )
}
end
end
diff --git a/app/datatables/neighbourhood_datatable.rb b/app/datatables/neighbourhood_datatable.rb
index 44f525235..9533b6161 100644
--- a/app/datatables/neighbourhood_datatable.rb
+++ b/app/datatables/neighbourhood_datatable.rb
@@ -8,6 +8,7 @@ def view_columns
unit_name: { source: 'Neighbourhood.unit_name' },
unit_code_key: { source: 'Neighbourhood.unit_code_key' },
unit_code_value: { source: 'Neighbourhood.unit_code_value' },
+ parent_name: { source: 'Neighbourhood.parent_name' },
}
end
@@ -19,10 +20,7 @@ def data
unit_name: record.unit_name,
unit_code_key: record.unit_code_key,
unit_code_value: record.unit_code_value,
- # county: record.county,
- # district: record.district,
- # region: record.region,
- # country: record.country
+ parent_name: record.parent_name,
}
end
end
diff --git a/app/helpers/sites_helper.rb b/app/helpers/sites_helper.rb
new file mode 100644
index 000000000..d16655577
--- /dev/null
+++ b/app/helpers/sites_helper.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module SitesHelper
+ def options_for_sites_neighbourhoods
+ # Remove the primary neighbourhood from the list
+ @all_neighbourhoods.filter { |e| e.name != '' }
+ .collect { |e| { name: e.contextual_name, id: e.id } }
+ end
+end
diff --git a/app/javascript/packs/admin.js b/app/javascript/packs/admin.js
index a64688328..34019d7a6 100644
--- a/app/javascript/packs/admin.js
+++ b/app/javascript/packs/admin.js
@@ -1,6 +1,6 @@
-require("cocoon")
-require("select2")
require("datatables.net-bs4")
+require("@nathanvda/cocoon")
+require("select2")
import 'bootstrap'
import 'vue'
@@ -12,7 +12,6 @@ import '../src/datatable.js'
import '../src/opening-times.js'
import '../src/ward-picker.js'
-
$(document).on('turbolinks:load', function () {
$('body').init_behaviors()
diff --git a/app/javascript/src/behaviors/all_behaviors.js b/app/javascript/src/behaviors/all_behaviors.js
index 7727b7a74..88b7359f2 100644
--- a/app/javascript/src/behaviors/all_behaviors.js
+++ b/app/javascript/src/behaviors/all_behaviors.js
@@ -4,4 +4,5 @@ import './behaviors.collection.js'
import './behaviors.neighbourhood.js'
import './behaviors.partner.js'
import './behaviors.place.js'
+import './behaviors.site.js'
import './behaviors.user.js'
diff --git a/app/javascript/src/behaviors/behaviors.site.js b/app/javascript/src/behaviors/behaviors.site.js
new file mode 100644
index 000000000..1ceae0ceb
--- /dev/null
+++ b/app/javascript/src/behaviors/behaviors.site.js
@@ -0,0 +1,20 @@
+jQuery.extend(Behaviors, {
+ site: {
+ form: {
+ init: function() {
+ // If the sites neighbourhood's relation_type is primary, it generates a label
+ // with the class 'cocoon_delete-this'. This allows us to remove it from the form
+ // so it does not submit a primary relation as being a secondary one or remove it
+ $('.cocoon_delete-this').parents('.nested-fields').remove();
+
+ // Attach select2 to the current select2 nodes
+ $('.select2').each(function () { $(this).select2({ multiple: false }); });
+
+ // Attach select2 to all future select2 nodes
+ $('.sites_neighbourhoods').bind('cocoon:after-insert', function (_, element) {
+ $('.select2', element).select2({ multiple: false });
+ });
+ }
+ }
+ }
+});
diff --git a/app/javascript/src/datatable.js b/app/javascript/src/datatable.js
index d47f80272..8d6c35384 100644
--- a/app/javascript/src/datatable.js
+++ b/app/javascript/src/datatable.js
@@ -10,15 +10,23 @@ document.addEventListener("turbolinks:before-cache", function () {
});
document.addEventListener('turbolinks:load', function () {
- dataTable = $('#datatable').DataTable({
- "processing": true,
- "serverSide": true,
- "pageLength": 15,
- "ajax": {
- "url": $('#datatable').data('source')
- },
- "pagingType": "full_numbers",
- // Column spec is loaded from a script tag in the view
- "columns": columns
- })
+ try {
+ dataTable = $('#datatable').DataTable({
+ "processing": true,
+ "serverSide": true,
+ "pageLength": 15,
+ "ajax": {
+ "url": $('#datatable').data('source')
+ },
+ "pagingType": "full_numbers",
+ // Column spec is loaded from a script tag in the view
+ "columns": columns
+ })
+ } catch (e) {
+ // On pages where DataTables shouldn't be used, columns is not defined.
+ // This catches that and stops it throwing an error to the console.
+ if (!(e instanceof ReferenceError)) {
+ console.error(e);
+ }
+ }
});
diff --git a/app/models/neighbourhood.rb b/app/models/neighbourhood.rb
index cacf065ea..48a4a1cd3 100644
--- a/app/models/neighbourhood.rb
+++ b/app/models/neighbourhood.rb
@@ -19,6 +19,8 @@ class Neighbourhood < ApplicationRecord
length: { is: 9 },
allow_blank: true
+ before_update :inject_parent_name_field
+
def shortname
if name_abbr.present?
name_abbr
@@ -29,13 +31,21 @@ def shortname
end
end
+ def contextual_name
+ # "Wardname, Countryname (Region)"
+ return "#{shortname}, #{parent_name} (#{unit.titleize})" if parent_name
+
+ # "Wardname (Region)"
+ "#{shortname} (#{unit.titleize})"
+ end
+
def fullname
if name.present?
- name
+ name
elsif name_abbr.present?
name_abbr
else
- "[not set]"
+ '[not set]'
end
end
@@ -67,4 +77,11 @@ def find_from_postcodesio_response(res)
unit_name: res['admin_ward'])
end
end
+
+ private
+
+ def inject_parent_name_field
+ self.parent_name = parent.name if parent
+ true
+ end
end
diff --git a/app/models/sites_neighbourhood.rb b/app/models/sites_neighbourhood.rb
index 7656ca50f..1c5d5e4c7 100644
--- a/app/models/sites_neighbourhood.rb
+++ b/app/models/sites_neighbourhood.rb
@@ -9,4 +9,8 @@ class SitesNeighbourhood < ApplicationRecord
scope: :site_id,
message: 'Neighbourhood cannot be assigned more than once to a site'
}
+
+ def name
+ neighbourhood.to_s
+ end
end
diff --git a/app/views/admin/sites/_form.html.erb b/app/views/admin/sites/_form.html.erb
index 5ddc68352..15013901d 100644
--- a/app/views/admin/sites/_form.html.erb
+++ b/app/views/admin/sites/_form.html.erb
@@ -49,38 +49,38 @@
Who took this photo?
Main neighbourhood
+ This neighbourhood will be listed in the main PlaceCal directory. It cannot be changed after the site is created.
- <%= f.fields_for :sites_neighbourhood do |sn| %>
+ <%= f.simple_fields_for :sites_neighbourhood do |sn| %>
<% if @primary_neighbourhood_id %>
- <%= @all_neighbourhoods.find(@primary_neighbourhood_id).name %>
+ <%= @all_neighbourhoods.find(@primary_neighbourhood_id).contextual_name %>
+ <%= sn.hidden_field :relation_type, value: "Primary" %>
+ <%= sn.hidden_field :neighbourhood_id, value: @primary_neighbourhood_id %>
<% else %>
<%= sn.hidden_field :relation_type, value: "Primary" %>
- <%= sn.select :neighbourhood_id, options_from_collection_for_select(@all_neighbourhoods, 'id', 'name', @primary_neighbourhood_id), class: 'form-control', include_blank: true %>
+ <%= sn.input :neighbourhood_id, collection: options_for_sites_neighbourhoods, include_blank: false,
+ value_method: ->(obj) { obj[:id] }, label_method: ->(obj) { obj[:name] },
+ input_html: { class: 'form-control select2 col-6' },
+ label: '', label_html: { hidden: true } %>
<% end %>
<% end %>
+
Other neighbourhoods to include
+ Information from these neighbourhoods will also be displayed on this site
-
- <% @all_neighbourhoods.each do |neighbourhood| %>
- <%= fields_for "site[sites_neighbourhoods_attributes][#{neighbourhood.id}]" do |sna|%>
-
- <% end %>
+
+ <%= f.simple_fields_for :sites_neighbourhoods do |neighbourhood| %>
+ <%= render 'sites_neighbourhood_fields', :f => neighbourhood %>
<% end %>
+
+ <%= link_to_add_association 'Add neighbourhood', f, :sites_neighbourhoods, class: "btn btn-primary btn-sm" %>
+
+
- <%= f.button :submit, class: "btn btn-primary " %>
+ <%= f.button :submit, class: "btn btn-primary btn-lg" %>
<% unless @site.new_record? %>
- <%= link_to "Destroy Site", admin_site_path(@site), method: :delete, class: "btn btn-danger" %>
+ <%= link_to "Destroy Site", admin_site_path(@site), method: :delete, class: "btn btn-danger btn-lg" %>
<% end %>
<% end %>
diff --git a/app/views/admin/sites/_sites_neighbourhood_fields.html.erb b/app/views/admin/sites/_sites_neighbourhood_fields.html.erb
new file mode 100644
index 000000000..d3b79e481
--- /dev/null
+++ b/app/views/admin/sites/_sites_neighbourhood_fields.html.erb
@@ -0,0 +1,16 @@
+
diff --git a/db/migrate/20220125175817_add_parent_name_field_to_neighbourhoods.rb b/db/migrate/20220125175817_add_parent_name_field_to_neighbourhoods.rb
new file mode 100644
index 000000000..5cfbde6f1
--- /dev/null
+++ b/db/migrate/20220125175817_add_parent_name_field_to_neighbourhoods.rb
@@ -0,0 +1,7 @@
+class AddParentNameFieldToNeighbourhoods < ActiveRecord::Migration[6.1]
+ def change
+ add_column :neighbourhoods, :parent_name, :string
+
+ Neighbourhood.find_each(&:save)
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index d65e98be1..7e45750cc 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2022_01_24_170103) do
+ActiveRecord::Schema.define(version: 2022_01_25_175817) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -125,6 +125,7 @@
t.string "unit_code_key", default: "WD19CD"
t.string "unit_code_value"
t.string "unit_name"
+ t.string "parent_name"
t.index ["ancestry"], name: "index_neighbourhoods_on_ancestry"
end
diff --git a/package.json b/package.json
index fd5a88700..0c9b62746 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
"yarn": ">= 1.21.1"
},
"dependencies": {
+ "@nathanvda/cocoon": "^1.2.14",
"@rails/ujs": "^6.0.2",
"@rails/webpacker": "5.4.3",
"axios": "^0.24.0",
diff --git a/test/integration/admin/sites_integration_test.rb b/test/integration/admin/sites_integration_test.rb
index 92b12ca36..ae8065310 100644
--- a/test/integration/admin/sites_integration_test.rb
+++ b/test/integration/admin/sites_integration_test.rb
@@ -35,10 +35,17 @@ class AdminSitesIntegrationTest < ActionDispatch::IntegrationTest
assert_select 'label', 'Hero image'
assert_select 'label', 'Hero image credit'
- # See all neighbourhoods
- assert_select '.site__neighbourhoods' do
- assert_select 'label', @number_of_neighbourhoods
- end
+ # See just neighbourhoods they admin
+ # In short:
+ # - Find the cocoon template for the Secondary Neighbourhoods