Skip to content

Commit

Permalink
Dm 3508 map component (#541)
Browse files Browse the repository at this point in the history
* dm-3508

Adding support/dependencies for map component.

* dm-3508

Page Builder UI

* dm-3508

* dm-3508

documenting page_map_components schema

* dm-3508

backend and infrastructure for front end.

* dm-3508

* dm-3508

bus logic: fetching diffusion histories for selected practices.

* dm-3508

* dm-3508

center map and zoom

* dm-3508

styles, zoom level

* dm-3508

Fix query for adopting facilities

* dm-3508

removed dbg

* dm-3508

removed dbgs

* dm-3508

marker infowindow

* dm-3508

info window

* dm-3508

logic for statuses

* dm-3508

front end stuff

* dm-3508

info window styling text changes.

* dm-3508

border radius..

* dm-3508

map zoom

* dm-3508

border padding for info window card style

* dm-3508

use padding shorthand

* dm-3508

add margin between description and map bottom.

* dm-3508

info window static size.

* dm-3508

infowindow styles...

* dm-3508

Added in Abbr Short_name for info window content.. i.e., 23 "XR" innovations.. for a specific Facility.

* dm-3508

margin above num innovations in infowindow

* dm-3508

schema change

* dm-3508

added test.

* dm-3508

* dm-3508

fixed issue with text wrapping and ignoring padding.

* dm-3508

info window styles

* dm-3508

make map component mobile friendly.

* dm-3508

more info window and border styles for map component info window.

* dm-3508

* dm-3508

* dm-3508

info window styles

* dm-3508

addressing testing and PR comments.

* dm-3508

refactored some code to use ActiveRecord vs arrays.

* dm-3508

Refactored some code in the controller.

* dm-3508

renamed infowindow partial to _page_map_infowindow

* dm-3508

another slight refactor...

* dm-3508

UPdate based on PR comments.

* dm-3508

Fixed styling for Info Window Facility Link.

* dm-3508

Map and info window styles.. enums for Diffusion History statuses.. etc.

* dm-3508

Addend links for innovations within the map component markers info-window

* dm-3508

forgot to update these changes in schema.rb

* dm-3508

remove commented code and fix margin in info window.

* dm-3508

Added model test.

* dm-3508

more tests for map

* dm-3508

try to fix test.

* dm-3508

Fix test.

* dm-3508

* dm-3508

ok.. lets try different syntax..

* m-3508

display-none?

* dm-3508

forgot the div

* dm-3508

* dm-3508

* dm-3508

* dm-3508

info window styles

* dm-3508

* dm-3508

info window size and positioning

* dm-3508

* dm-3508

* dm-3508

Style changes per design.

* dm-3508

spec for clicking map marker and displaying infowindow

* dm-3508

err in spec.

* dm-3508

Admin Panel test page for creating a map component

* dm-3508

removed debuggers

* dm-3508

Admin panel spec

* dm-3508

Update IDs to match db change for "display_successful_adoptions" for spec.

* Revert "dm-3508"

This reverts commit 8e352bd

* dm-3508

re-factor spec

* dm-3508

more refactor for specs

* dm-3508

* dm-3508

info window spec

* dm-3508

setting ids back to be consistent in map_page_comonent_form.html.arb

* dm-3508

find the map marker...

* dm-3508

Remove other community features from schema that are in other component branches.

* dm-3508

PR updates.

* dm-3508

PR updates

* dm-3508

pr suggestions

* dm-3508

moved helper method to model - refactored method.

* dm-3508

* dm-3508

test not working now...

* dm-3508

PR Comments

* dm-3508

InfoWindow refactors

* dm-3508

Update/Refactor short_name column to map_info_window_text

* dm-3508

updated page_map_component.short_name field to map_info_window_text.

* dm-3508

Update tests for map due to column name change.

* dm-3508

update spec for page_map_component field name change.

* dm-3508

pr comments.

* dm-3508

INfo Window styles.

* dm-3508

Decrease maxWidth and maxHeight

* dm-3508

removed commented code from spec.

* dm-3508

adjustedpixel offset for new maxWidth, maxHeight.

* dm-3508

Fix indent for comment headers.

* dm-3508

revert back to "if" instead of "unless"

* Removed duplicate code in admin/pages.rb

Co-authored-by: Joshua Drumm <[email protected]>
  • Loading branch information
bradjohnson92008 and JoshingYou1 authored Oct 12, 2022
1 parent c00a190 commit ca728ae
Show file tree
Hide file tree
Showing 20 changed files with 422 additions and 15 deletions.
12 changes: 11 additions & 1 deletion app/admin/pages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
:cta_text,
:button_text,
:card,
:display_successful_adoptions,
:display_in_progress_adoptions,
:display_unsuccessful_adoptions,
:map_info_window_text,
:body,
:title_header,
:text_alignment,
Expand Down Expand Up @@ -119,14 +123,17 @@
if (pc.component_type == 'PageHeader3Component' ||
pc.component_type == 'PageSubpageHyperlinkComponent' ||
pc.component_type == 'PageAccordionComponent' ||
pc.component_type == 'PageMapComponent' ||
pc.component_type == 'PageCompoundBodyComponent') && component&.title.present?
para "Title: #{component.title}"
end
# Large title
para "Large title: #{component.large_title}" if pc.component_type == 'PageCompoundBodyComponent' && component&.large_title
# Description
if (pc.component_type == 'PageHeader3Component' ||
pc.component_type == 'PageDownloadableFileComponent') && component&.description.present?
pc.component_type == 'PageDownloadableFileComponent' ||
pc.component_type == 'PageMapComponent') &&
component&.description.present?
para component.description
end
# Text
Expand Down Expand Up @@ -155,6 +162,9 @@
para component&.alt_text if pc.component_type == 'PageImageComponent'
# Attachment file name
para component&.attachment_file_name if pc.component_type == 'PageDownloadableFileComponent'
# Map Info Window Text
para component&.map_info_window_text if pc.component_type == 'PageMapComponent' && component&.map_info_window_text != ''

# Display name
para component&.display_name if pc.component_type == 'PageDownloadableFileComponent' && component&.display_name.present?
# Margin bottom
Expand Down
3 changes: 2 additions & 1 deletion app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,5 @@
//= require visns/visn_va_facility_infowindow
//= require jquery.collapser.js
//= require category_usage.js
//= require tinymce
//= require tinymce
//= require page/page_infowindow
22 changes: 22 additions & 0 deletions app/assets/javascripts/page/page_infowindow.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class @PageInfoBoxBuilder extends Gmaps.Google.Builders.Marker # inherit from base builder
# override method
create_infowindow: ->
return null unless _.isString @args.infowindow
boxText = document.createElement("div")
boxText.setAttribute('class', 'page-marker-container') #to customize
boxText.innerHTML = @args.infowindow
@infowindow = new InfoBox(@infobox(boxText))

# add @bind_infowindow() for < 2.1

infobox: (boxText)->
content: boxText
pixelOffset: new google.maps.Size(-200, 137)
boxStyle: {
maxWidth: "400px",
maxHeight: "275px",
overflow: "auto",
backgroundColor: "white",
paddingBottom: "52px"
}
alignBottom: true
51 changes: 51 additions & 0 deletions app/assets/javascripts/page/page_map.es6
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
function initialize() {
const handler = Gmaps.build('Google', {
markers: {
clusterer: null
},
builders: {
Marker: PageInfoBoxBuilder
}
});
let markers;
let dataMarkers;

function buildMapMarkers(data) {
dataMarkers = _.map(data, function (json, index) {
json.marker = markers[index];
return json;
});
}

handler.buildMap({
provider: {
center: {lat: 39.8097343, lng: -98.5556199},
zoom: 4.2,
zoomControlOptions: {
position: google.maps.ControlPosition.TOP_RIGHT
},
fullscreenControl: false,
mapTypeControl: false,
streetViewControl: false
},
internal: {id: 'page_builder_map'},
markers: {
options: {
rich_marker: true
}
}
},
function () {
markers = handler.addMarkers(mapData);
buildMapMarkers(mapData);
});

google.maps.event.addListener(handler.getMap(), "idle", function () {
$("#page_builder_map").removeClass("display-none");
$(".dm-facilities-show-map-loading-spinner").addClass("display-none");
});
}

$(document).on("turbolinks:load", function () {
google.maps.event.addDomListener(window, "load", initialize);
});
21 changes: 20 additions & 1 deletion app/assets/stylesheets/dm/components/page_component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,30 @@
}
}

.page-map-component {
.page-marker-container {
padding: 52px 8px 0 8px;
}

.infoBox {
img {
@include u-position('absolute');
@include u-right('105');
@include u-top('105');
}
}
}

.page_builder_map {
height: 440px;
}
}

.page-event-component {
border-top: 1px solid black;
}

.page-news-component {
@include u-margin-bottom(2);
}
}

39 changes: 39 additions & 0 deletions app/controllers/page_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ def show
page_slug = params[:page_slug] ? params[:page_slug] : 'home'
@page = Page.includes(:page_group).find_by(slug: page_slug.downcase, page_groups: {slug: params[:page_group_friendly_id].downcase})
@page_components = @page.page_components
get_map_components(@page_components)
@path_parts = request.path.split('/')
@facilities_data = VaFacility.cached_va_facilities.order_by_station_name
@practice_list_components = []
Expand All @@ -22,8 +23,46 @@ def show
end
end


private

def get_map_components(page_components)
page_components.each do |pc|
if pc.component_type == "PageMapComponent"
@map_component = PageMapComponent.find_by_id(pc.component_id)
build_map_component(@map_component.get_adopting_facility_ids)
end
end
end

def build_map_component(adopting_facility_ids)
va_facilities = VaFacility.where(id: adopting_facility_ids)
@va_facility_marker = Gmaps4rails.build_markers(va_facilities) do |facility, marker|
marker.lat facility.latitude
marker.lng facility.longitude
marker.picture({
url: view_context.image_path('map-marker-default.svg'),
width: 34,
height: 46,
scaledWidth: 34,
scaledHeight: 46
})
marker.shadow nil
marker.json({ id: facility.id })
adoption_count = DiffusionHistory.where(va_facility_id: facility.id).count
practice_data = @map_component.get_practice_data_by_diffusion_histories(facility.id)
marker.infowindow render_to_string(
partial: 'maps/page_map_infowindow',
locals: {
facility: facility,
map_component: @map_component,
practice_data: practice_data,
adoption_count: adoption_count
}
)
end
end

def collect_paginated_components(page_components)
practice_lists = []
events = []
Expand Down
1 change: 1 addition & 0 deletions app/models/page_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def destroy_component
'Subpage Hyperlink': 'PageSubpageHyperlinkComponent',
'YouTube Player': 'PageYouTubePlayerComponent',
'Horizontal Separator': 'PageHrComponent',
'Google Map': 'PageMapComponent',
'Text and Images': 'PageCompoundBodyComponent'
}

Expand Down
35 changes: 35 additions & 0 deletions app/models/page_map_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class PageMapComponent < ApplicationRecord
has_one :page_component, as: :component, autosave: true

def get_practice_data_by_diffusion_histories(facility_id)
adoptions = DiffusionHistory.where(va_facility_id: facility_id)
info_window_practice_data = []
adoptions.each do |adoption|
adoption_practice = DiffusionHistory.get_with_practice(adoption.practice).first.practice
if practices.include?(adoption_practice.id.to_s)
info_window_practice_data << adoption_practice.slice(:name, :short_name, :tagline, :slug)
end
end
info_window_practice_data
end

def get_adopting_facility_ids
va_facility_ids = []
practices.each do |pr|
diffusion_histories = DiffusionHistory.where(practice_id: pr)
diffusion_histories.each do |dh|
dhs = DiffusionHistoryStatus.where(diffusion_history_id: dh[:id]).first.status
unless dh.va_facility_id.nil?
if (dhs == 'Completed' || dhs == 'Implemented' || dhs == 'Complete') && display_successful_adoptions
va_facility_ids.push dh.va_facility_id
elsif (dhs == 'In progress' || dhs == 'Planning' || dhs == 'Implementing') && display_in_progress_adoptions
va_facility_ids.push dh.va_facility_id
elsif dhs == "Unsuccessful" && display_unsuccessful_adoptions
va_facility_ids.push dh.va_facility_id
end
end
end
end
va_facility_ids
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ f.has_many page_components, heading: nil, sortable: :position, sortable_start: 1
pc.template.concat(render partial: 'page_hr_component_form', locals: {component: component.class == PageHrComponent ? component : nil, placeholder: placeholder})
pc.template.concat(render partial: 'page_downloadable_file_component_form', locals: {component: component.class == PageDownloadableFileComponent ? component : nil, placeholder: placeholder})
pc.template.concat(render partial: 'page_cta_component_form', locals: {component: component.class == PageCtaComponent ? component : nil, placeholder: placeholder})
pc.template.concat(render partial: 'page_map_component_form', locals: {component: component.class == PageMapComponent ? component : nil, placeholder: placeholder})
pc.template.concat(
render partial: 'page_compound_body_component_form',
locals: {
Expand Down
84 changes: 84 additions & 0 deletions app/views/active_admin/resource/_page_map_component_form.html.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# TODO: get the placeholder how active admin does "NEW_#{association_human_name.upcase.split(' ').join('_')}_RECORD"
placeholder ||= 'NEW_PAGE_COMPONENT_RECORD' # = "NEW_#{association_human_name.upcase.split(' ').join('_')}_RECORD"
component ||= nil
html = Arbre::Context.new do
li "", id: "PageMapComponent_poly_#{placeholder}", class: "input polyform component-#{placeholder}" do
fieldset class: "inputs" do
legend do
span 'Map'
end
ol do
if component
input type: 'hidden', value: component.id, name: "page[page_components_attributes][#{placeholder}][component_attributes][id]"
end

li class: 'url input required stringish', id: "page_page_components_attributes_#{placeholder}_component_attributes_title_input" do
label 'Title', for: "page_page_components_attributes_#{placeholder}_component_attributes_title", class: 'label'
input value: component&.title || nil, type: 'text', required: 'required',
id: "page_page_components_attributes_#{placeholder}_component_attributes_title",
name: "page[page_components_attributes][#{placeholder}][component_attributes][title]"
para 'Enter a title for the map.', class: 'inline-hints'
end

li class: 'url input required stringish', id: "page_page_components_attributes_#{placeholder}_component_attributes_map_info_window_text_input" do
label 'Map Info Window Text', for: "page_page_components_attributes_#{placeholder}_component_attributes_map_info_window_text", class: 'label'
input value: component&.map_info_window_text || nil, type: 'text', required: 'required',
id: "page_page_components_attributes_#{placeholder}_component_attributes_map_info_window_text",
name: "page[page_components_attributes][#{placeholder}][component_attributes][map_info_window_text]"
para 'Enter text or acronym to display in the maps info window.', class: 'inline-hints'
end

li class: 'url input required stringish', id: "page_page_components_attributes_#{placeholder}_component_attributes_description_input" do
label 'Description', for: "page_page_components_attributes_#{placeholder}_component_attributes_description", class: 'label'
input value: component&.description || nil, type: 'text', required: 'required',
id: "page_page_components_attributes_#{placeholder}_component_attributes_description",
name: "page[page_components_attributes][#{placeholder}][component_attributes][description]"
para 'Enter a brief description of the map.', class: 'inline-hints'
end

li class: 'select input optional', id: "page_page_components_attributes_#{placeholder}_practices_attributes_input" do
label 'Innovation List', for: "page_page_components_attributes_#{placeholder}_component_attributes_map", class: 'label'
select required: 'required', multiple: 'multiple', size: '20',
id: "page_page_components_attributes_#{placeholder}_component_attributes_map",
name: "page[page_components_attributes][#{placeholder}][component_attributes][practices][]" do
Practice.order(name: :asc).each do |p|
option p.name, value: p.id, selected: component&.practices&.include?(p.id.to_s) ? 'selected' : nil
end
end
para 'Select which Innovations adoptions are displayed on the map. Hold down the CTRL key and click on Innovation names to add to the list.', class: 'inline-hints'
end

li class: 'checkbox input optional', id: "page_page_components_attributes_#{placeholder}_component_attributes_display_successful_adoptions_input" do
if component
input type: 'hidden', value: '0', name: "page[page_components_attributes][#{placeholder}][component_attributes][display_successful_adoptions]"
end
label 'Successful', for: "page_page_components_attributes_#{placeholder}_component_attributes_display_successful_adoptions", class: 'label'
input value: component&.display_successful_adoptions || nil, type: 'checkbox', checked: component&.display_successful_adoptions?,
id: "page_page_components_attributes_#{placeholder}_component_attributes_display_successful_adoptions",
name: "page[page_components_attributes][#{placeholder}][component_attributes][display_successful_adoptions]"
end
li class: 'checkbox input optional', id: "page_page_components_attributes_#{placeholder}_component_attributes_display_in_progress_adoptions_input" do
if component
input type: 'hidden', value: '0', name: "page[page_components_attributes][#{placeholder}][component_attributes][display_in_progress_adoptions]"
end
label 'In Progress', for: "page_page_components_attributes_#{placeholder}_component_attributes_display_in_progress_adoptions", class: 'label'
input value: '1', type: 'checkbox', checked: component&.display_in_progress_adoptions?,
id: "page_page_components_attributes_#{placeholder}_component_attributes_display_in_progress_adoptions",
name: "page[page_components_attributes][#{placeholder}][component_attributes][display_in_progress_adoptions]"
end
li class: 'checkbox input optional', id: "page_page_components_attributes_#{placeholder}_component_attributes_display_unsuccessful_adoptions_input" do
if component
input type: 'hidden', value: '0', name: "page[page_components_attributes][#{placeholder}][component_attributes][display_unsuccessful_adoptions]"
end
label 'Unsuccessful', for: "page_page_components_attributes_#{placeholder}_component_attributes_display_unsuccessful_adoptions", class: 'label'
input value: '1', type: 'checkbox', checked: component&.display_unsuccessful_adoptions?,
id: "page_page_components_attributes_#{placeholder}_component_attributes_display_unsuccessful_adoptions",
name: "page[page_components_attributes][#{placeholder}][component_attributes][display_unsuccessful_adoptions]"
end
para 'Select which adoptions statuses should display on the map.', class: 'inline-hints'
end
end
end
end

return html.to_s
30 changes: 30 additions & 0 deletions app/views/maps/_page_map_infowindow.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<div class="line-height-sans-1">
<div class="margin-top-1">
<%
station_name = facility.official_station_name
map_info_window_text = map_component.map_info_window_text
%>
<p class="margin-0 padding-x-4">
<%= link_to "#{station_name} #{ show_common_name(station_name, facility.common_name)}", va_facility_path(facility), class: 'usa-link font-sans-md text-bold' %>
</p>
<div class="margin-top-0 text-normal theme-type-scale-sm padding-x-4">
<%= adoption_count %> <%= map_info_window_text.present? ? "#{map_info_window_text}" : 'Total' %> Innovation<%= 's' if adoption_count != 1 %>
</div>
<div class="text-bold font-sans-3xs">
<% practice_data.each do |pd| %>
<%
info_window_text = pd[:map_info_window_text]
name = pd[:name]
%>
<div class="radius-lg border border-solid padding-x-4 padding-y-105 border-base-lightest margin-bottom-2">
<a class="usa-link" href="/innovations/<%= pd[:slug] %>">
<%= info_window_text.present? ? "#{name} (#{info_window_text})" : "#{name}" %>
</a>
<div class="text-normal font-sans-3xs margin-top-3">
<%= pd[:tagline] %>
</div>
</div>
<% end %>
</div>
</div>
</div>
10 changes: 10 additions & 0 deletions app/views/page/_page_map.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<% if ENV['GOOGLE_API_KEY'].present? %>
<% provide :head_tags do %>
<%= javascript_tag 'data-turbolinks-track': 'reload' do %>
var mapData = <%= raw @va_facility_marker.to_json %>
<% end %>
<%= javascript_include_tag 'page/page_map', 'data-turbolinks-track': 'reload' %>
<% end %>
<div id="page_builder_map" class="display-none grid-col-12 desktop:grid-col-9 page_builder_map"></div>
<%= render partial: 'shared/loading_spinner', locals: { display: true, classes: 'flex-justify-center flex-align-self-center margin-y-8 desktop:margin-y-10 dm-facilities-show-map-loading-spinner text-center' } %>
<% end %>
1 change: 1 addition & 0 deletions app/views/page/_page_map_data.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
var mapData = <%= raw @va_facility_marker.to_json %>;
Loading

0 comments on commit ca728ae

Please sign in to comment.