Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIT-766-1 race condition bug fix #2687

Merged
merged 25 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
96cd260
SIT-765 enable place name field at Lucas' request
jookyg Nov 18, 2023
0bebe31
Merge branch 'master' of github.com:eGovPDX/portlandor into sit-765
jookyg Nov 27, 2023
6241ccb
SIT-766 enable Place Name field
jookyg Nov 27, 2023
e488278
SIT-766 added disable place name autofill config option
jookyg Nov 27, 2023
19f7f28
Merge branch 'sit-765' into sit-766
jookyg Nov 27, 2023
b7970cb
SIT-766 final form updates
jookyg Nov 27, 2023
4380dc0
SIT-766 text formatting minor updates
jookyg Nov 27, 2023
4b1b099
SIT-766 updated confirmation verbiage, fixed bug that was clearing pl…
jookyg Nov 27, 2023
bc03ac8
SIT-766 tweaks to confirmation messages
jookyg Nov 28, 2023
0fea4a8
SIT-766 fixed bug in location widget that caused point to be selected…
jookyg Nov 28, 2023
bb5b153
SIT-766 rearranged private property answers and updated verbiage
jookyg Nov 28, 2023
14271dc
SIT-766 turned off previous submissions feature
jookyg Nov 28, 2023
1c89e2a
Merge branch 'master' of github.com:eGovPDX/portlandor into sit-766
jookyg Nov 28, 2023
1bf742b
SIT-766 fixed location widget bug that prevented location_address fro…
jookyg Nov 28, 2023
7a365da
SIT-766 update to private property next steps, vehicle next steps, AD…
jookyg Nov 28, 2023
1ef6d5d
SIT-766 added sentence to confirmation at Lucas' request
jookyg Nov 29, 2023
b9eca61
Merge branch 'master' of github.com:eGovPDX/portlandor into sit-766
jookyg Nov 29, 2023
bf6d349
SIT-766-1 added timeout check when checking boundaries to prevent rac…
jookyg Nov 30, 2023
aebca65
SIT-766-1 added timeout checker on regions layer
jookyg Nov 30, 2023
a412442
SIT-766-1 hide loader when status or error modals are displayed.
jookyg Nov 30, 2023
d5a3169
SIT-766-1 removed commented code, cleanup
jookyg Nov 30, 2023
e8116e7
SIT-766-1 removed commented code, cleanup
jookyg Nov 30, 2023
fae141a
SIT-766-1 added accessible loading message
jookyg Nov 30, 2023
5d50d09
SIT-766-1 fixed heading levels
jookyg Nov 30, 2023
015c5da
SIT-766 Skip the deletion of multi-dev
kxwang Dec 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,9 @@ build_and_deploy: &build_and_deploy
then
echo "Start to delete multi-dev..."
while read env_name; do
terminus multidev:delete --delete-branch $CIRCLE_PROJECT_REPONAME.$env_name -y
echo "Deleted multi-dev: $env_name"
echo "Skipped deleting multi-dev: $env_name"
# terminus multidev:delete --delete-branch $CIRCLE_PROJECT_REPONAME.$env_name -y
# echo "Deleted multi-dev: $env_name"
done <./matching_env_list.txt
echo "Done deleting multi-dev"
rm -f ./matching_env_list.txt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,35 @@ span#verified-text {
border: dashed 1px red;
padding: 0 3px;
}

#location_map {
position: relative;
}

.loader-container {
display: none;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10000;
}

/* The actual loader */
.loader {
border: 8px solid #f3f3f3;
border-top: 8px solid #3498db;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
}

/* Animation for the loader */
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
var featureLayerVisibleZoom = drupalSettings.webform && drupalSettings.webform.portland_location_picker.feature_layer_visible_zoom ? drupalSettings.webform.portland_location_picker.feature_layer_visible_zoom : FEATURE_LAYER_VISIBLE_ZOOM;
var requireCityLimits = drupalSettings.webform && drupalSettings.webform.portland_location_picker.require_city_limits === true ? true : false;
var requireCityLimitsPlusParks = drupalSettings.webform && drupalSettings.webform.portland_location_picker.require_city_limits_plus_parks === true ? true : false;
var disablePlaceNameAutofill = drupalSettings.webform && drupalSettings.webform.portland_location_picker.disable_place_name_autofill === true ? true : false;

var boundaryUrl = drupalSettings.webform ? drupalSettings.webform.portland_location_picker.boundary_url : "";
var displayBoundary = drupalSettings.webform && drupalSettings.webform.portland_location_picker.display_boundary === false ? false : true;
Expand Down Expand Up @@ -228,16 +229,6 @@
// force a crosshair cursor
$('.leaflet-container').css('cursor', 'crosshair');

// if there are coordinates in the hidden lat/lng fields, set the map marker.
// this may be a submit postback that had validation errors, so we need to re set it.
var lat = $('input[name=' + elementId + '\\[location_lat\\]]').val();
var lng = $('input[name=' + elementId + '\\[location_lon\\]]').val();
if (lat && lng && lat !== "0" && lng !== "0") {
setLocationMarker(lat, lng);
doZoomAndCenter(lat, lng);
doMapClick(new L.LatLng(lat, lng));
}

// Set up address verify button, autocomplete, and help text
$('#location_search').after(`<input class="button button--primary location-verify js-form-submit form-submit" type="button" id="location_verify" name="op" value="${verifyButtonText}">`);
$('#location_search').on('keyup', function (e) {
Expand Down Expand Up @@ -296,6 +287,47 @@

// INITIALIZE GEOJSON LAYERS //////////
processGeoJsonData();

// if there are coordinates in the hidden lat/lng fields, set the map marker.
// this may be a submit postback that had validation errors, so we need to re set it.
// WARNING: if boundaryLayer isn't loaded yet, this will fail in checkWithinBounds().
restoreLocationFromPostback();
}

function restoreLocationFromPostback() {
var lat = $('input[name=' + elementId + '\\[location_lat\\]]').val();
var lng = $('input[name=' + elementId + '\\[location_lon\\]]').val();
if (lat && lng && lat !== "0" && lng !== "0") {
showLoader();

if (requireBoundary) {
if (boundaryLayer) {
setLocationMarker(lat, lng);
doZoomAndCenter(lat, lng);
doMapClick(new L.LatLng(lat, lng));

} else {
setTimeout(function () {
if (boundaryLayer) {
setLocationMarker(lat, lng);
doZoomAndCenter(lat, lng);
doMapClick(new L.LatLng(lat, lng));

} else {
restoreLocationFromPostback();
}
}, 1000);
}

} else {
setLocationMarker(lat, lng);
doZoomAndCenter(lat, lng);
doMapClick(new L.LatLng(lat, lng));
}

// WARNING: Need to wait until boundaryLayer and regions layers are loaded, if applicable

}
}

function initializeSearchAutocomplete() {
Expand Down Expand Up @@ -371,16 +403,21 @@

if (boundaryUrl) {
$.ajax({
url: boundaryUrl, success: function (cityBoundaryResponse) {
url: boundaryUrl,
success: function (cityBoundaryResponse) {
var cityBoundaryFeatures = cityBoundaryResponse.features;
boundaryLayer = L.geoJson(cityBoundaryFeatures, cityLimitsProperties).addTo(map);
if (boundaryLayer.municipality) {
boundaryLayer.municipality = cityBoundaryFeatures[0].properties.CITYNAME;
}
// if boundary is shown, display a map key
// $('.leaflet-container').after('<div class="mt-1"><p><em>Please select a location within the <span class="boundary-key">marked boundary area(s)</span>.</em></p></div>');

console.log("Boundary layer loaded.");
},
error: function (e) {
// if the PortlandMaps API is down, this is where we'll get stuck.
// any way to fail the location lookup gracefull and still let folks submit?
// at least display an error message.
console.error(e);
showErrorModal("An error occurred while attemping to load the boundary layer.");
}
});
}
Expand All @@ -392,6 +429,8 @@
if (primaryLayerSource) {
primaryLayer = L.geoJson(); // can we create this on the fly?

showLoader();

$.ajax({
url: primaryLayerSource, success: function (primaryResponse) {
primaryFeatures = primaryResponse.features;
Expand Down Expand Up @@ -442,13 +481,27 @@
initPrimaryLayer(primaryFeatures, primaryLayer);
}

hideLoader();

if (regionsLayerSource) {
showLoader();
$.ajax({
url: regionsLayerSource, success: function (regionsResponse) {
url: regionsLayerSource,
async: false,
success: function (regionsResponse) {
regionsFeatures = regionsResponse.features;
console.log(regionsFeatures.length + " regions found.");

initRegionsLayer(regionsFeatures, regionsLayer);
hideLoader();
},
error: function (e) {
// if the PortlandMaps API is down, this is where we'll get stuck.
// any way to fail the location lookup gracefull and still let folks submit?
// at least display an error message.
console.error(e);
showErrorModal("An error occurred while attemping to load the regions layer.");
hideLoader();
}
});
}
Expand Down Expand Up @@ -529,9 +582,7 @@
layer.on("mouseover", function (e) { layer.openPopup(e.latlng); });
layer.on("mousemove", function (e) { layer.openPopup(e.latlng); });
layer.on("mouseout", function (e) { layer.closePopup(); });
// layer.on("click", handleMapClick);
} else {
// layer.on("click", handleMarkerClick);
}
}

Expand Down Expand Up @@ -757,6 +808,9 @@
}

function doMapClick(latlng) {
// show loading indicator
showLoader();

// normally when the map is clicked, we want to zoom to the clicked location
// and perform reverse geocoding.

Expand All @@ -768,10 +822,6 @@
resetLocationMarker();
clearLocationFields();

// clear place name and park selector fields; they will get reset if appropriate after the click.
$('.place-name').val("");
$('#location_park').val("");

if (locCircle) {
map.removeLayer(locCircle);
locateControlContaier.style.backgroundImage = 'url("/modules/custom/portland/modules/portland_location_picker/images/map_locate.png")';
Expand All @@ -780,6 +830,14 @@
reverseGeolocate(latlng);
}

function showLoader() {
$('.loader-container').css("display","flex");
}

function hideLoader() {
$('.loader-container').css("display","none");
}

function checkRegion(latlng) {
// determine whether click is within a region on the primaryLayer layer, and store the region_id.
// this is done if the primary layer type is Region, or if the regions layer is populated.
Expand All @@ -790,17 +848,34 @@
} else {
testLayer = primaryLayer;
}
var inLayer = leafletPip.pointInLayer(latlng, testLayer, false);
if (inLayer.length > 0) {
// NOTE: The following code would be problematic if we allow multiple copies of the widget or alternate naming conventions.
$('input[name=' + elementId + '\\[location_region_id\\]]').val(inLayer[0].feature.properties.region_id);

showLoader();
if (testLayer.options.interactive) {
checkClickInRegion(latlng, testLayer);
} else {
// clear region_id field
$('input[name=' + elementId + '\\[location_region_id\\]]').val("");
setTimeout(function () {
if (testLayer.options.interactive) {
checkClickInRegion(latlng, testLayer);
} else {
checkRegion(latlng);
}
}, 1000);
}
}
}

function checkClickInRegion(latlng, testLayer) {
var inLayer = leafletPip.pointInLayer(latlng, testLayer, false);
if (inLayer.length > 0) {
// NOTE: The following code would be problematic if we allow multiple copies of the widget or alternate naming conventions.
$('input[name=' + elementId + '\\[location_region_id\\]]').val(inLayer[0].feature.properties.region_id);
} else {
// clear region_id field
$('input[name=' + elementId + '\\[location_region_id\\]]').val("");
}
hideLoader();
}

function isAssetSelectable(marker) {
// defines the criteria under which an asset can be selected
if (primaryLayerBehavior != PRIMARY_LAYER_BEHAVIOR.Selection && primaryLayerBehavior != PRIMARY_LAYER_BEHAVIOR.SelectionOnly) {
Expand Down Expand Up @@ -862,11 +937,15 @@
$('input[name=' + elementId + '\\[location_lon\\]]').val('');
$('input[name=' + elementId + '\\[location_x\\]]').val('');
$('input[name=' + elementId + '\\[location_y\\]]').val('');
$('input[name=' + elementId + '\\[place_name\\]]').val('');
$('input[name=' + elementId + '\\[location_asset_id\\]]').val('');
$('input[name=' + elementId + '\\[location_region_id\\]]').val('');
$('input[name=' + elementId + '\\[location_municipality_name\\]]').val('');
$('input[name=' + elementId + '\\[location_attributes\\]]').val('');

// only clear place name if autofill is disabled
if (!disablePlaceNameAutofill) {
$('input[name=' + elementId + '\\[place_name\\]]').val('');
}
}

function setLocationDetails(results) {
Expand Down Expand Up @@ -1026,7 +1105,7 @@
showVerifiedLocation(fulladdress, lat, lng);

// put park name in place_name field
if (candidates[0].attributes.location_type == "PARK") {
if (candidates[0].attributes.location_type == "PARK" && !disablePlaceNameAutofill) {
$('#place_name').val(fulladdress);
}

Expand Down Expand Up @@ -1093,7 +1172,7 @@

function captureSelectedAssetMarkerData(marker) {
// copy asset title to place name field
if (marker.target.feature.properties.name) {
if (marker.target.feature.properties.name && !disablePlaceNameAutofill) {
$('#place_name').val(marker.target.feature.properties.name);
}

Expand Down Expand Up @@ -1156,6 +1235,8 @@
setLatLngHiddenFields(latlng.lat, latlng.lng);
reverseGeolocate(latlng);
});

hideLoader();
}

function reverseGeolocate(latlng, zoomAndCenter = true) {
Expand All @@ -1173,10 +1254,10 @@

$.ajax({
url: url, success: function (response) {
if (response.length < 1 || !response.address || !response.location) {
// location data not available, how to handle?
console.log('Location not found');
}
// if (response.length < 1 || !response.address || !response.location) {
// // location data not available, how to handle?
// console.log('Location not found');
// }
processReverseLocationData(response, latlng.lat, latlng.lng, zoomAndCenter);
},
error: function (e) {
Expand All @@ -1196,7 +1277,9 @@
// if park, get park name
if (data.park && data.detail.park[0].name != null) {
description = data.detail.park[0].name.toUpperCase();
$('#place_name').val(data.detail.park[0].name);
if (!disablePlaceNameAutofill) {
$('#place_name').val(data.detail.park[0].name);
}
} else if (data.waterbody && data.detail.waterbody[0].name != null) {
description = data.detail.waterbody[0].name.toUpperCase();
} else {
Expand Down Expand Up @@ -1259,7 +1342,6 @@
var description = parseDescribeData(data, isWithinBounds);

showVerifiedLocation(description, lat, lng, isWithinBounds, isVerifiedAddress);
$('#location_address').val(description);

// if park, set location name
if (data.park) {
Expand Down Expand Up @@ -1291,6 +1373,7 @@
};

if (isVerifiedAddress) setVerified();
$('#location_address').val(description);
}

function hideVerifiedLocation() {
Expand Down Expand Up @@ -1329,6 +1412,7 @@
}

function showStatusModal(message) {
hideLoader();
statusModal.html('<p class="status-message mb-0">' + message + '</p>');
Drupal.dialog(statusModal, {
width: '600px',
Expand All @@ -1353,7 +1437,8 @@
}

function showErrorModal(message) {
message = message + "<br><br>" + ERROR_MODAL_DEFAULT_TEXT;// '<br><br>Please try again in a few moments. If the error persists, please <a href="/feedback">contact us</a>.';
hideLoader();
message = message + "<br><br>" + ERROR_MODAL_DEFAULT_TEXT;
showStatusModal(message);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static function getCompositeElements(array $element) {
'#description' => '',
'#description_display' => 'before',
'#title_display' => 'invisible',
'#markup' => '<div id="location_map_container" class="location-map"></div>',
'#markup' => '<div id="location_map_container" class="location-map"></div><div class="loader-container" role="status"><div class="loader"></div><div class="visually-hidden">Loading...</div></div>',
];
$element['suggestions_modal'] = [
'#type' => 'markup',
Expand Down
Loading