map providers
This commit is contained in:
Generated
+19
@@ -854,6 +854,25 @@
|
||||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="metadata/app/mapProviders">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
<option name="generatedName" value="New Schema" />
|
||||
<option name="name" value="metadata/app/mapProviders" />
|
||||
<option name="relativePathToSchema" value="schema/metadata/app/mapProviders.json" />
|
||||
<option name="schemaVersion" value="JSON Schema version 7" />
|
||||
<option name="patterns">
|
||||
<list>
|
||||
<Item>
|
||||
<option name="pattern" value="true" />
|
||||
<option name="path" value="*/Resources/metadata/app/mapProviders.json" />
|
||||
<option name="mappingKind" value="Pattern" />
|
||||
</Item>
|
||||
</list>
|
||||
</option>
|
||||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="metadata/app/massActions">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
|
||||
Vendored
+6
@@ -352,6 +352,12 @@
|
||||
],
|
||||
"url": "./schema/metadata/app/entityManager.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"*/Resources/metadata/app/mapProviders.json"
|
||||
],
|
||||
"url": "./schema/metadata/app/mapProviders.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"*/Resources/metadata/app/massActions.json"
|
||||
|
||||
@@ -256,6 +256,7 @@ return [
|
||||
'newNotificationCountInTitle' => false,
|
||||
'pdfEngine' => 'Dompdf',
|
||||
'smsProvider' => null,
|
||||
'mapProvider' => 'Google',
|
||||
'defaultFileStorage' => 'EspoUploadDir',
|
||||
'ldapUserNameAttribute' => 'sAMAccountName',
|
||||
'ldapUserFirstNameAttribute' => 'givenName',
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"Google": {
|
||||
"renderer": "handlers/map/google-maps-renderer"
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,5 @@
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"name": "provider",
|
||||
"type": "enum",
|
||||
"options": [
|
||||
"Google"
|
||||
],
|
||||
"default": "Google"
|
||||
},
|
||||
{
|
||||
"name": "height",
|
||||
"type": "int",
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
import MapRenderer from 'handlers/map/renderer';
|
||||
|
||||
class GoogleMapsRenderer extends MapRenderer {
|
||||
|
||||
/**
|
||||
* @param {module:handlers/map/renderer~addressData} addressData
|
||||
*/
|
||||
render(addressData) {
|
||||
if ('google' in window && window.google.maps) {
|
||||
this.initMapGoogle(addressData);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// noinspection SpellCheckingInspection
|
||||
if (typeof window.mapapiloaded === 'function') {
|
||||
// noinspection SpellCheckingInspection
|
||||
const mapapiloaded = window.mapapiloaded;
|
||||
|
||||
// noinspection SpellCheckingInspection
|
||||
window.mapapiloaded = () => {
|
||||
this.initMapGoogle(addressData);
|
||||
|
||||
mapapiloaded();
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// noinspection SpellCheckingInspection
|
||||
window.mapapiloaded = () => this.initMapGoogle(addressData);
|
||||
|
||||
let src = 'https://maps.googleapis.com/maps/api/js?callback=mapapiloaded';
|
||||
const apiKey = this.view.getConfig().get('googleMapsApiKey');
|
||||
|
||||
if (apiKey) {
|
||||
src += '&key=' + apiKey;
|
||||
}
|
||||
|
||||
const scriptElement = document.createElement('script');
|
||||
|
||||
scriptElement.setAttribute('async', 'async');
|
||||
scriptElement.src = src;
|
||||
|
||||
document.head.appendChild(scriptElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:handlers/map/renderer~addressData} addressData
|
||||
*/
|
||||
initMapGoogle(addressData) {
|
||||
// noinspection JSUnresolvedReference
|
||||
const geocoder = new google.maps.Geocoder();
|
||||
let map;
|
||||
|
||||
try {
|
||||
// noinspection SpellCheckingInspection,JSUnresolvedReference
|
||||
map = new google.maps.Map(this.view.$el.find('.map').get(0), {
|
||||
zoom: 15,
|
||||
center: {lat: 0, lng: 0},
|
||||
scrollwheel: false,
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e.message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let address = '';
|
||||
|
||||
if (addressData.street) {
|
||||
address += addressData.street;
|
||||
}
|
||||
|
||||
if (addressData.city) {
|
||||
if (address !== '') {
|
||||
address += ', ';
|
||||
}
|
||||
|
||||
address += addressData.city;
|
||||
}
|
||||
|
||||
if (addressData.state) {
|
||||
if (address !== '') {
|
||||
address += ', ';
|
||||
}
|
||||
|
||||
address += addressData.state;
|
||||
}
|
||||
|
||||
if (addressData.postalCode) {
|
||||
if (addressData.state || addressData.city) {
|
||||
address += ' ';
|
||||
}
|
||||
else {
|
||||
if (address) {
|
||||
address += ', ';
|
||||
}
|
||||
}
|
||||
|
||||
address += addressData.postalCode;
|
||||
}
|
||||
|
||||
if (addressData.country) {
|
||||
if (address !== '') {
|
||||
address += ', ';
|
||||
}
|
||||
|
||||
address += addressData.country;
|
||||
}
|
||||
|
||||
// noinspection JSUnresolvedReference
|
||||
geocoder.geocode({'address': address}, (results, status) => {
|
||||
// noinspection JSUnresolvedReference
|
||||
if (status === google.maps.GeocoderStatus.OK) {
|
||||
// noinspection JSUnresolvedReference
|
||||
map.setCenter(results[0].geometry.location);
|
||||
|
||||
// noinspection JSUnresolvedReference
|
||||
new google.maps.Marker({
|
||||
map: map,
|
||||
position: results[0].geometry.location,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export default GoogleMapsRenderer;
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @module handlers/map/renderer
|
||||
*/
|
||||
|
||||
/**
|
||||
* A map renderer.
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
class MapRenderer {
|
||||
|
||||
/**
|
||||
* @typedef {Object} module:handlers/map/renderer~addressData
|
||||
* @property {string|null} street
|
||||
* @property {string|null} city
|
||||
* @property {string|null} country
|
||||
* @property {string|null} state
|
||||
* @property {string|null} postalCode
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {import('views/fields/map').default} view A field view.
|
||||
*/
|
||||
constructor(view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:handlers/map/renderer~addressData} addressData
|
||||
* @abstract
|
||||
*/
|
||||
render(addressData) {}
|
||||
}
|
||||
|
||||
export default MapRenderer;
|
||||
+31
-130
@@ -28,10 +28,14 @@ class MapFieldView extends BaseFieldView {
|
||||
detailTemplate = 'fields/map/detail'
|
||||
listTemplate = 'fields/map/detail'
|
||||
|
||||
addressField = null
|
||||
provider = null
|
||||
/** @type {string} */
|
||||
addressField
|
||||
/** @type {string} */
|
||||
provider
|
||||
height = 300
|
||||
|
||||
DEFAULT_PROVIDER = 'Google';
|
||||
|
||||
// noinspection JSCheckFunctionSignatures
|
||||
data() {
|
||||
const data = super.data();
|
||||
@@ -45,7 +49,7 @@ class MapFieldView extends BaseFieldView {
|
||||
setup() {
|
||||
this.addressField = this.name.slice(0, this.name.length - 3);
|
||||
|
||||
this.provider = this.options.provider || this.params.provider;
|
||||
this.provider = this.provider || this.getConfig().get('mapProvider') || this.DEFAULT_PROVIDER;
|
||||
this.height = this.options.height || this.params.height || this.height;
|
||||
|
||||
const addressAttributeList = Object.keys(this.getMetadata().get('fields.address.fields') || {})
|
||||
@@ -93,71 +97,43 @@ class MapFieldView extends BaseFieldView {
|
||||
this.$map = this.$el.find('.map');
|
||||
|
||||
if (this.hasAddress()) {
|
||||
this.processSetHeight(true);
|
||||
|
||||
if (this.height === 'auto') {
|
||||
$(window).off('resize.' + this.cid);
|
||||
$(window).on('resize.' + this.cid, this.processSetHeight.bind(this));
|
||||
}
|
||||
|
||||
let methodName = 'afterRender' + this.provider.replace(/\s+/g, '');
|
||||
|
||||
if (typeof this[methodName] === 'function') {
|
||||
this[methodName]();
|
||||
}
|
||||
else {
|
||||
let implClassName = this.getMetadata()
|
||||
.get(['clientDefs', 'AddressMap', 'implementations', this.provider]);
|
||||
|
||||
if (implClassName) {
|
||||
Espo.loader.require(implClassName, impl => {
|
||||
impl.render(this);
|
||||
});
|
||||
}
|
||||
}
|
||||
this.renderMap();
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
afterRenderGoogle() {
|
||||
if (window.google && window.google.maps) {
|
||||
this.initMapGoogle();
|
||||
renderMap() {
|
||||
this.processSetHeight(true);
|
||||
|
||||
if (this.height === 'auto') {
|
||||
$(window).off('resize.' + this.cid);
|
||||
$(window).on('resize.' + this.cid, this.processSetHeight.bind(this));
|
||||
}
|
||||
|
||||
const rendererId = this.getMetadata().get(['app', 'mapProviders', this.provider, 'renderer']);
|
||||
|
||||
if (rendererId) {
|
||||
Espo.loader.require(rendererId, Renderer => {
|
||||
(new Renderer(this)).render(this.addressData);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// noinspection SpellCheckingInspection
|
||||
if (typeof window.mapapiloaded === 'function') {
|
||||
// noinspection SpellCheckingInspection
|
||||
let mapapiloaded = window.mapapiloaded;
|
||||
const methodName = 'afterRender' + this.provider.replace(/\s+/g, '');
|
||||
|
||||
// noinspection SpellCheckingInspection
|
||||
window.mapapiloaded = () => {
|
||||
this.initMapGoogle();
|
||||
mapapiloaded();
|
||||
};
|
||||
if (typeof this[methodName] === 'function') {
|
||||
this[methodName]();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// noinspection SpellCheckingInspection
|
||||
window.mapapiloaded = () => {
|
||||
this.initMapGoogle();
|
||||
};
|
||||
// For bc.
|
||||
// @todo Remove in v9.0.
|
||||
const implId = this.getMetadata().get(['clientDefs', 'AddressMap', 'implementations', this.provider]);
|
||||
|
||||
let src = 'https://maps.googleapis.com/maps/api/js?callback=mapapiloaded';
|
||||
let apiKey = this.getConfig().get('googleMapsApiKey');
|
||||
|
||||
if (apiKey) {
|
||||
src += '&key=' + apiKey;
|
||||
if (implId) {
|
||||
Espo.loader.require(implId, impl => impl.render(this));
|
||||
}
|
||||
|
||||
let scriptElement = document.createElement('script');
|
||||
|
||||
scriptElement.setAttribute('async', 'async');
|
||||
scriptElement.src = src;
|
||||
|
||||
document.head.appendChild(scriptElement);
|
||||
}
|
||||
|
||||
processSetHeight(init) {
|
||||
@@ -167,9 +143,7 @@ class MapFieldView extends BaseFieldView {
|
||||
height = this.$el.parent().height();
|
||||
|
||||
if (init && height <= 0) {
|
||||
setTimeout(() => {
|
||||
this.processSetHeight(true);
|
||||
}, 50);
|
||||
setTimeout(() => this.processSetHeight(true), 50);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -177,79 +151,6 @@ class MapFieldView extends BaseFieldView {
|
||||
|
||||
this.$map.css('height', height + 'px');
|
||||
}
|
||||
|
||||
initMapGoogle() {
|
||||
const geocoder = new google.maps.Geocoder();
|
||||
let map;
|
||||
|
||||
try {
|
||||
// noinspection SpellCheckingInspection
|
||||
map = new google.maps.Map(this.$el.find('.map').get(0), {
|
||||
zoom: 15,
|
||||
center: {lat: 0, lng: 0},
|
||||
scrollwheel: false,
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e.message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let address = '';
|
||||
|
||||
if (this.addressData.street) {
|
||||
address += this.addressData.street;
|
||||
}
|
||||
|
||||
if (this.addressData.city) {
|
||||
if (address !== '') {
|
||||
address += ', ';
|
||||
}
|
||||
|
||||
address += this.addressData.city;
|
||||
}
|
||||
|
||||
if (this.addressData.state) {
|
||||
if (address !== '') {
|
||||
address += ', ';
|
||||
}
|
||||
|
||||
address += this.addressData.state;
|
||||
}
|
||||
|
||||
if (this.addressData.postalCode) {
|
||||
if (this.addressData.state || this.addressData.city) {
|
||||
address += ' ';
|
||||
}
|
||||
else {
|
||||
if (address) {
|
||||
address += ', ';
|
||||
}
|
||||
}
|
||||
|
||||
address += this.addressData.postalCode;
|
||||
}
|
||||
|
||||
if (this.addressData.country) {
|
||||
if (address !== '') {
|
||||
address += ', ';
|
||||
}
|
||||
|
||||
address += this.addressData.country;
|
||||
}
|
||||
|
||||
geocoder.geocode({'address': address}, (results, status) => {
|
||||
if (status === google.maps.GeocoderStatus.OK) {
|
||||
map.setCenter(results[0].geometry.location);
|
||||
|
||||
new google.maps.Marker({
|
||||
map: map,
|
||||
position: results[0].geometry.location,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default MapFieldView;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://www.espocrm.com/schema/metadata/app/mapProviders.json",
|
||||
"title": "app/mapProviders",
|
||||
"description": "Map providers.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"description": "A provider name.",
|
||||
"properties": {
|
||||
"renderer": {
|
||||
"type": "string",
|
||||
"description": "A frontend renderer. Should extend handlers/map/renderer."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user