UNPKG

maplibre-gl-js-amplify

Version:

MapLibre Plugin to Support Amplify Geo Integration

400 lines (399 loc) 21.8 kB
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, }; }