PageSourceSearch

https://careers.ccs.spokane.edu/assets/sites/controllers/blocks/google_map/map_controller-1d02e9ff.js

js spokane.edu collected 2026-09-24 09:43:10 UTC 4,475 bytes, 122 lines download raw bytes

1import {Controller} from '@hotwired/stimulus'
2import MarkerClusterer from '@googlemaps/markerclustererplus'
3import {CommonGoogleMaps} from 'common/google_maps'
4import logRequest from 'sites/log_requests'
5import URI from 'urijs'
6
7export default class extends Controller {
8  static values = {jobSearchParams: Object, postMarkersUrl:String}
9
10  connect() {
11    if (window.js_vars.bot) {
12      this.element.classList.add('map-placeholder')
13    } else {
14      if (window.js_vars.google_maps) {
15        this.loadGoogleMapsAndSetUp()
16      }
17    }
18  }
19
20  loadGoogleMapsAndSetUp() {
21    import('@googlemaps/js-api-loader').then(({setOptions, importLibrary}) => {
22      setOptions({key: window.js_vars.google_maps.api_key})
23      Promise.all([importLibrary('maps'), importLibrary('core'), importLibrary('marker')])
24        .then(([maps, core, markerLib]) => {
25          const googleMaps = {...maps, ...core, ...markerLib}
26          this.setUpMapWhenVisible(googleMaps)
27        })
28    })
29  }
30
31  setUpMapWhenVisible(googleMaps) {
32    const observer = new IntersectionObserver((entries, observer) => {
33      for (const entry of entries) {
34        if (entry.intersectionRatio > 0) {
35          this.initMap(googleMaps)
36          this.addStaticOrAsyncMarkers(googleMaps)
37          observer.disconnect()
38        }
39      }
40    })
41    observer.observe(this.element)
42  }
43
44  initMap(googleMaps) {
45    logRequest('start_google_map')
46    const mapOptions = JSON.parse(this.element.dataset.mapOptions)
47    this.map = new googleMaps.Map(this.element, mapOptions)
48    this.map.setCenter(this.buildLocation(googleMaps, this.element.dataset.defaultCentreLat, this.element.dataset.defaultCentreLng))
49    this.bounds = new googleMaps.LatLngBounds()
50    this.markerClusterer = new MarkerClusterer(this.map, [], {
51      styles: [
52        { width: 30, height: 30, className: 'cluster-icon-1' },
53        { width: 40, height: 40, className: 'cluster-icon-2' },
54        { width: 50, height: 50, className: 'cluster-icon-3' },
55      ],
56      clusterClass: 'cluster-icon',
57      maxZoom: 14,
58    })
59    this.infoWindow = new googleMaps.InfoWindow()
60    this.map.addListener('click', () => this.infoWindow.close())
61  }
62
63  addStaticOrAsyncMarkers(googleMaps) {
64    const markerData = this.element.dataset.markerData
65    if (markerData) {
66      this.updateMarkers(googleMaps, JSON.parse(markerData))
67      const nearbyMarkerData = this.element.dataset.nearbyMarkerData
68      if (nearbyMarkerData) {
69        this.addMarkers(googleMaps, JSON.parse(nearbyMarkerData), '/images/google_maps/spotlight-poi2-blue.png')
70      }
71    } else {
72      this.fetchMarkersAndUpdateMap(googleMaps)
73      document.addEventListener('clinch:job_search_results_updated', 
73({detail: {jobSearchParamsAsJson}}) => {
74        this.jobSearchParamsValue = jobSearchParamsAsJson ? JSON.parse(jobSearchParamsAsJson) : {}
75        this.fetchMarkersAndUpdateMap(googleMaps)
76      })
77    }
78  }
79
80  fetchMarkersAndUpdateMap(googleMaps) {
81    if (this.hasPostMarkersUrlValue) {
82      const markerApiPathWithParams= URI(this.postMarkersUrlValue).addSearch(this.jobSearchParamsValue).toString()
83      fetch(markerApiPathWithParams)
84        .then(response => response.json())
85        .then(({markers}) => this.updateMarkers(googleMaps, markers))
86    }
87  }
88
89  buildLocation(googleMaps, lat, lng) {
90    return new googleMaps.LatLng(parseFloat(lat || 0.0), parseFloat(lng || 0.0))
91  }
92
93  updateMarkers(googleMaps, allMarkerData) {
94    this.markerClusterer.clearMarkers()
95    this.addMarkers(googleMaps, allMarkerData)
96  }
97
98  addMarkers(googleMaps, allMarkerData, icon = null) {
99    const markers = allMarkerData.map((markerData) => this.createMarker(googleMaps, markerData, icon))
100
101    if (markers.length) {
102      this.markerClusterer.addMarkers(markers)
103      this.bounds = new googleMaps.LatLngBounds()
104      for (const marker of this.markerClusterer.getMarkers()) {
105        this.bounds.extend(marker.getPosition())
106      }
107      this.map.setCenter(this.bounds.getCenter())
108      CommonGoogleMaps.setZoom(this.map, this.bounds, parseInt(this.element.dataset.defaultZoom))
109    }
110  }
111
112  createMarker(googleMaps, {lat, lng, info_window_content}, icon) {
113    const marker = new googleMaps.Marker({position: this.buildLocation(googleMaps, lat, lng), icon: icon})
114
115    marker.addListener('click', () => {
116      this.infoWindow.close()
117      this.infoWindow.setContent(info_window_content)
118      this.infoWindow.open(this.map, marker)
119    })
120    return marker
121  }
122}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.