maplibre-gl-js-amplify
Version:
MapLibre Plugin to Support Amplify Geo Integration
400 lines (399 loc) • 21.8 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { debounce } from 'debounce';
import { createElement, removeElement } from '../utils';
import { createErrorIcon } from './icons';
import { createEditIcon, createPopupStep1Icon, createPopupStep2Icon, createPopupStep3Icon, createPopupStep4Icon, createTrashIcon, createDeleteSuccessIcon, createCloseIcon, } from './icons';
export function AmplifyGeofenceControlUI(geofenceControl, geofenceControlContainer) {
let _addGeofenceContainer;
let _deleteGeofenceContainer;
let _addGeofencebutton;
let _checkboxAll;
let _geofenceList;
let _createContainer;
let _geofenceTitle;
let _checkBoxAllAndCreateContainer;
let _checkBoxAllContainer;
let _circleModeContainer;
let _polygonModeContainer;
let _deletePopdownContainer;
let _errorDiv;
let _geofenceCreateRadiusInput;
function registerControlPosition(map, positionName) {
if (map._controlPositions[positionName]) {
return;
}
const positionContainer = document.createElement('div');
positionContainer.className = `maplibregl-ctrl-${positionName}`;
map._controlContainer.appendChild(positionContainer);
map._controlPositions[positionName] = positionContainer;
}
/************************************************************
* Create Geofence Controls
*************************************************************/
function createGeofenceCreateContainer(isCircle) {
const container = createElement('div', 'geofence-ctrl-create-prompt-container', geofenceControlContainer);
_createContainer = createElement('div', 'geofence-ctrl-create-prompt', container);
if (isCircle) {
/* Create buttons to switch between different modes */
const buttonContainer = createElement('div', 'geofence-ctrl-create-prompt-buttons', _createContainer);
const circleModeButton = createElement('div', 'geofence-ctrl-create-prompt-button-circle geofence-ctrl-create-prompt-button', buttonContainer);
circleModeButton.addEventListener('click', () => {
// Change button selected style
circleModeButton.classList.add('geofence-ctrl-create-prompt-selected');
polygonModeButton.classList.remove('geofence-ctrl-create-prompt-selected');
// Switch info box mode
if (_polygonModeContainer) {
removeElement(_polygonModeContainer);
_polygonModeContainer = undefined;
}
if (!_circleModeContainer)
createCircleModeCreateContainer(_createContainer);
geofenceControl.changeMode('draw_circle');
});
circleModeButton.innerHTML = 'Circle';
const polygonModeButton = createElement('div', 'geofence-ctrl-create-prompt-button-polygon geofence-ctrl-create-prompt-button', buttonContainer);
polygonModeButton.addEventListener('click', () => {
geofenceControl.changeMode('draw_polygon');
// Change button selected style
polygonModeButton.classList.add('geofence-ctrl-create-prompt-selected');
circleModeButton.classList.remove('geofence-ctrl-create-prompt-selected');
// Switch info box mode
if (_circleModeContainer) {
removeElement(_circleModeContainer);
_circleModeContainer = undefined;
}
if (!_polygonModeContainer)
createPolygonModeCreateContainer(_createContainer);
});
polygonModeButton.innerHTML = 'Custom';
circleModeButton.classList.add('geofence-ctrl-create-prompt-selected');
createCircleModeCreateContainer(_createContainer);
}
else {
createPolygonModeCreateContainer(_createContainer);
}
}
function createCircleModeCreateContainer(container) {
_circleModeContainer = createElement('div', 'geofence-ctrl-create-circle-mode-container', container);
const radiusTitle = createElement('div', 'geofence-ctrl-create-circle-mode-title', _circleModeContainer);
radiusTitle.innerHTML = 'Radius';
_geofenceCreateRadiusInput = createElement('input', 'geofence-ctrl-create-circle-mode-input', _circleModeContainer);
_geofenceCreateRadiusInput.addEventListener('keydown', debounce(geofenceControl.updateInputRadius, 200));
}
function createPolygonModeCreateContainer(container) {
_polygonModeContainer = createElement('div', 'geofence-ctrl-create-polygon-mode-container', container);
const moreInfoContainer = createElement('div', 'geofence-ctrl-create-polygon-mode-info-container', _polygonModeContainer);
const moreInfoIcon = createElement('div', 'geofence-ctrl-create-polygon-mode-icon', moreInfoContainer);
const letterI = createElement('div', 'geofence-ctrl-create-polygon-mode-info-icon', moreInfoIcon);
letterI.innerHTML = 'i';
const moreInfo = createElement('div', 'geofence-ctrl-create-polygon-mode-title', moreInfoContainer);
moreInfo.innerHTML = 'How it works?';
const resetButton = createElement('div', 'geofence-ctrl-create-polygon-mode-reset-button geofence-ctrl-button', _polygonModeContainer);
resetButton.innerHTML = 'Reset';
resetButton.addEventListener('click', () => {
geofenceControl.resetGeofence();
});
// Add popup onClick
const popup = createPolygonModeInfoPopup(moreInfoIcon);
moreInfoContainer.addEventListener('click', () => {
popup.classList.toggle('show');
});
}
function createPolygonModeInfoPopup(container) {
const popupContainer = createElement('div', 'geofence-ctrl-create-polygon-mode-popup-container', container);
const popup = createElement('div', 'geofence-ctrl-create-polygon-mode-popup', popupContainer);
createPopupStep(popup, 'Move dots to desired position', createPopupStep1Icon());
createPopupStep(popup, 'Click on a border to create a dot', createPopupStep2Icon());
createPopupStep(popup, 'Click into shape to move', createPopupStep3Icon());
createPopupStep(popup, 'Press delete to remove a dot', createPopupStep4Icon());
return popup;
}
function createPopupStep(container, text, image) {
const popupStep = createElement('div', 'geofence-ctrl-create-polygon-mode-popup-step', container);
const popupStepImage = createElement('div', 'geofence-ctrl-create-polygon-mode-popup-step-image', popupStep);
popupStepImage.appendChild(image);
const popupStepText = createElement('div', 'geofence-ctrl-create-polygon-mode-popup-step-text', popupStep);
popupStepText.innerHTML = text;
}
function removeGeofenceCreateContainer() {
removeElement(_createContainer);
_createContainer = undefined;
_circleModeContainer = undefined;
_polygonModeContainer = undefined;
}
/************************************************************
* Geofence List
*************************************************************/
function createGeofenceListContainer() {
const geofenceListContainer = createElement('div', 'geofence-ctrl-list-container', geofenceControlContainer);
createGeofenceListHeader(geofenceListContainer);
_geofenceList = createElement('div', 'geofence-ctrl-list', geofenceListContainer);
_geofenceList.addEventListener('scroll', () => {
const { scrollHeight, scrollTop, clientHeight } = _geofenceList;
if (scrollTop + clientHeight >= scrollHeight - 20) {
geofenceControl.loadMoreGeofences();
}
});
}
function createGeofenceListHeader(geofenceListContainer) {
const header = createElement('div', 'geofence-ctrl-list-header', geofenceListContainer);
_geofenceTitle = createElement('div', 'geofence-ctrl-list-header-title', header);
_geofenceTitle.innerHTML = 'Geofences (0)';
_checkBoxAllAndCreateContainer = createElement('div', 'geofence-ctrl-list-header-checkbox-create-container', header);
createCheckboxAllContainer(_checkBoxAllAndCreateContainer);
}
function createCheckboxAllContainer(geofenceListContainer) {
_checkBoxAllContainer = createElement('div', 'geofence-ctrl-list-checkbox-all-container', geofenceListContainer);
_checkboxAll = createElement('input', 'geofence-ctrl-list-checkbox-all', _checkBoxAllContainer);
_checkboxAll.type = 'checkbox';
_checkboxAll.addEventListener('click', function () {
if (_checkboxAll.checked) {
geofenceControl.displayAllGeofences();
checkboxAllText.innerHTML = 'Deselect All';
}
else {
geofenceControl.hideAllGeofences();
checkboxAllText.innerHTML = 'Select All';
}
});
const checkboxAllText = createElement('div', 'geofence-ctrl-list-checkbox-all-title', _checkBoxAllContainer);
checkboxAllText.innerHTML = 'Select all';
_addGeofencebutton = createElement('div', 'geofence-ctrl-list-header-add-button', _checkBoxAllContainer);
_addGeofencebutton.innerHTML = '+ Add';
_addGeofencebutton.addEventListener('click', () => {
createAddGeofenceContainer();
});
}
function renderListItem(geofence) {
const container = createElement('li', 'geofence-ctrl-list-item-container', _geofenceList);
container.id = `list-item-${geofence.geofenceId}`;
const listItem = createElement('li', 'geofence-ctrl-list-item', container);
const leftContainer = createElement('div', 'geofence-ctrl-list-item-left-container', listItem);
const checkbox = createElement('input', 'geofence-ctrl-list-item-checkbox', leftContainer);
checkbox.id = `list-item-checkbox-${geofence.geofenceId}`;
checkbox.type = 'checkbox';
checkbox.addEventListener('click', function () {
if (checkbox.checked) {
geofenceControl.displayGeofence(geofence.geofenceId);
geofenceControl.fitGeofence(geofence.geofenceId);
}
else {
geofenceControl.hideGeofence(geofence.geofenceId);
}
});
const rightContainer = createElement('div', 'geofence-ctrl-list-item-right-container', listItem);
const geofenceTitleContainer = createElement('div', 'geofence-ctrl-list-item-title-container', rightContainer);
geofenceTitleContainer.addEventListener('mouseover', function () {
geofenceControl.displayHighlightedGeofence(geofence.geofenceId);
});
geofenceTitleContainer.addEventListener('mouseout', function () {
geofenceControl.hideHighlightedGeofence();
});
const geofenceTitle = createElement('div', 'geofence-ctrl-list-item-title', geofenceTitleContainer);
geofenceTitle.innerHTML = geofence.geofenceId;
const editButton = createElement('div', 'geofence-ctrl-edit-button', geofenceTitleContainer);
editButton.addEventListener('click', function () {
geofenceControl.editGeofence(geofence.geofenceId);
createEditControls(listItem, rightContainer, leftContainer, geofence.geofenceId);
listItem.classList.remove('geofence-ctrl-list-item');
listItem.classList.add('geofence-ctrl-list-selected-item');
});
editButton.appendChild(createEditIcon());
}
function createEditControls(item, rightContainer, leftContainer, id) {
const editContainer = createElement('div', 'geofence-ctrl-list-item-controls', rightContainer);
const deleteButton = renderDeleteButton(leftContainer, id);
const removeEditContainer = () => {
item.classList.remove('geofence-ctrl-list-selected-item');
item.classList.add('geofence-ctrl-list-item');
removeElement(editContainer);
removeElement(deleteButton);
};
const cancelButton = createElement('div', 'geofence-ctrl-cancel-button', editContainer);
cancelButton.classList.add('geofence-ctrl-button');
cancelButton.innerHTML = 'Cancel';
cancelButton.addEventListener('click', () => {
geofenceControl.setEditingModeEnabled(false);
removeEditContainer();
});
const saveGeofenceButton = createElement('div', 'geofence-ctrl-save-button geofence-ctrl-button', editContainer);
saveGeofenceButton.addEventListener('click', () => __awaiter(this, void 0, void 0, function* () {
yield geofenceControl.saveGeofence();
removeEditContainer();
}));
saveGeofenceButton.title = 'Save';
saveGeofenceButton.innerHTML = 'Save';
}
/************************************************************
* Add Geofence Controls
*************************************************************/
function removeAddGeofenceContainer() {
removeElement(_addGeofenceContainer);
clearAddGeofenceError();
showCheckboxAllContainer();
}
function clearAddGeofenceError() {
if (_errorDiv) {
removeElement(_errorDiv);
_errorDiv = undefined;
}
}
function createAddGeofenceContainer() {
hideCheckboxAllContainer();
_addGeofenceContainer = createElement('div', 'geofence-ctrl-add-geofence-container', _checkBoxAllAndCreateContainer);
const addGeofencePrompt = createElement('div', 'geofence-ctrl-add-geofence', _addGeofenceContainer);
const nameInput = createElement('input', 'geofence-ctrl-add-geofence-input', addGeofencePrompt);
nameInput.placeholder = 'Enter name';
const buttonContainer = createElement('div', 'geofence-ctrl-add-geofence-buttons', addGeofencePrompt);
const cancelButton = createElement('div', 'geofence-ctrl-add-geofence-cancel-button geofence-ctrl-button ', buttonContainer);
cancelButton.innerHTML = 'Cancel';
cancelButton.addEventListener('click', () => {
removeAddGeofenceContainer();
geofenceControl.setEditingModeEnabled(false);
});
const saveButton = createElement('div', 'geofence-ctrl-button geofence-ctrl-save-button', buttonContainer);
saveButton.innerHTML = 'Save';
saveButton.addEventListener('click', function () {
return __awaiter(this, void 0, void 0, function* () {
clearAddGeofenceError();
const output = yield geofenceControl.createGeofence(escape(nameInput.value));
if (output)
removeAddGeofenceContainer();
});
});
geofenceControl.addEditableGeofence();
}
function createAddGeofencePromptError(error) {
if (_errorDiv) {
return;
}
_errorDiv = createElement('div', 'geofence-ctrl-add-geofence-error', _addGeofenceContainer);
const errorIconContainer = createElement('div', 'geofence-ctrl-add-geofence-error-icon', _errorDiv);
errorIconContainer.appendChild(createErrorIcon());
const errorText = createElement('div', 'geofence-ctrl-add-geofence-error-text', _errorDiv);
errorText.innerHTML = error;
}
/************************************************************
* Delete Controls
*************************************************************/
function renderDeleteButton(container, id) {
const deleteButton = createElement('div', 'geofence-ctrl-delete-button', container);
deleteButton.classList.add('geofence-ctrl-button');
deleteButton.addEventListener('click', function () {
createConfirmDeleteContainer(id);
});
deleteButton.appendChild(createTrashIcon());
return deleteButton;
}
function createConfirmDeleteContainer(geofenceId) {
_deleteGeofenceContainer = createElement('div', 'geofence-ctrl-delete-prompt-container', geofenceControlContainer);
const deleteGeofencePrompt = createElement('div', 'geofence-ctrl-delete-prompt', _deleteGeofenceContainer);
const title = createElement('div', 'geofence-ctrl-delete-geofence-title', deleteGeofencePrompt);
title.innerHTML = `Are you sure you want to delete <strong>${geofenceId}</strong>?`;
createDeleteButtonsContainer(deleteGeofencePrompt, geofenceId);
}
function createDeleteButtonsContainer(container, geofenceId) {
const deleteButtonsContainer = createElement('div', 'geofence-ctrl-delete-geofence-buttons', container);
const cancelButton = createElement('div', 'geofence-ctrl-delete-geofence-cancel-button', deleteButtonsContainer);
cancelButton.innerHTML = 'Cancel';
cancelButton.addEventListener('click', () => {
removeElement(_deleteGeofenceContainer);
});
const confirmDeleteButton = createElement('div', 'geofence-ctrl-delete-geofence-confirm-button', deleteButtonsContainer);
confirmDeleteButton.innerHTML = 'Delete';
confirmDeleteButton.addEventListener('click', function () {
return __awaiter(this, void 0, void 0, function* () {
const id = yield geofenceControl.deleteGeofence(geofenceId);
if (id) {
createDeleteResultContainer(true);
removeElement(_deleteGeofenceContainer);
geofenceControl.setEditingModeEnabled(false);
}
});
});
}
function createDeleteResultContainer(success) {
_deletePopdownContainer = createElement('div', 'geofence-ctrl-delete-popdown-container', geofenceControlContainer);
const deletePopdown = createElement('div', 'geofence-ctrl-delete-popdown', _deletePopdownContainer);
const deletePopdownCloseButton = createElement('div', 'geofence-ctrl-delete-popdown-close-button', _deletePopdownContainer);
deletePopdownCloseButton.appendChild(createCloseIcon());
deletePopdownCloseButton.addEventListener('click', () => {
removeElement(_deletePopdownContainer);
});
const deleteSuccessIcon = createElement('div', 'geofence-ctrl-delete-popdown-icon', deletePopdown);
deleteSuccessIcon.appendChild(createDeleteSuccessIcon());
const deletePopdownText = createElement('div', 'geofence-ctrl-delete-popdown-text', deletePopdown);
deletePopdownText.innerHTML = success
? 'Geofence was deleted successfully'
: 'Geofence failed to delete';
}
/************************************************************
* Utility Methods
*************************************************************/
function updateCheckbox(geofenceId, checked) {
const checkbox = document.getElementById(`list-item-checkbox-${geofenceId}`);
if (checkbox)
checkbox.checked = checked;
}
function removeGeofenceListItem(geofenceId) {
const listItem = document.getElementById(`list-item-${geofenceId}`);
removeElement(listItem);
}
function setGeofenceListEnabled(enabled) {
_checkboxAll.disabled = !enabled;
enabled
? _addGeofencebutton.classList.remove('geofence-ctrl-noHover')
: _addGeofencebutton.classList.add('geofence-ctrl-noHover');
const inputs = document.getElementsByClassName('geofence-ctrl-list-item-checkbox');
for (let i = 0; i < inputs.length; i++) {
inputs.item(i).disabled = !enabled;
}
const items = document.getElementsByClassName('geofence-ctrl-list-item-container');
for (let i = 0; i < items.length; i++) {
enabled
? items.item(i).classList.remove('geofence-ctrl-noHover')
: items.item(i).classList.add('geofence-ctrl-noHover');
}
}
function getCheckboxAllValue() {
return _checkboxAll.checked;
}
function updateGeofenceCount(count) {
_geofenceTitle.innerHTML = `Geofences (${count})`;
}
function updateGeofenceRadius(radius) {
if (_geofenceCreateRadiusInput)
_geofenceCreateRadiusInput.value = `${radius}`;
}
function hideCheckboxAllContainer() {
_checkBoxAllContainer.style.display = 'none';
}
function showCheckboxAllContainer() {
_checkBoxAllContainer.style.display = 'flex';
}
return {
registerControlPosition,
createElement,
removeElement,
createGeofenceCreateContainer,
createGeofenceListContainer,
removeAddGeofenceContainer,
createAddGeofencePromptError,
renderListItem,
updateCheckbox,
removeGeofenceListItem,
setGeofenceListEnabled,
getCheckboxAllValue,
removeGeofenceCreateContainer,
updateGeofenceCount,
updateGeofenceRadius,
};
}