mirror of
https://github.com/umap-project/umap.git
synced 2025-05-04 13:41:49 +02:00
Compare commits
5 commits
b0eb263d93
...
51e41b7bce
Author | SHA1 | Date | |
---|---|---|---|
![]() |
51e41b7bce | ||
![]() |
b49f3d7633 | ||
![]() |
0dbac92853 | ||
![]() |
6d56bbb5de | ||
![]() |
e1a24b6180 |
12 changed files with 61 additions and 317 deletions
|
@ -1,37 +1,13 @@
|
|||
import {
|
||||
uMapAlert as Alert,
|
||||
uMapAlertCreation as AlertCreation,
|
||||
} from '../components/alerts/alert.js'
|
||||
import {
|
||||
AjaxAutocomplete,
|
||||
AjaxAutocompleteMultiple,
|
||||
AutocompleteDatalist,
|
||||
} from './autocomplete.js'
|
||||
import Browser from './browser.js'
|
||||
import Caption from './caption.js'
|
||||
import ContextMenu from './ui/contextmenu.js'
|
||||
import Facets from './facets.js'
|
||||
import { Formatter } from './formatter.js'
|
||||
import { uMapAlert as Alert } from '../components/alerts/alert.js'
|
||||
import { AjaxAutocomplete, AjaxAutocompleteMultiple } from './autocomplete.js'
|
||||
import Help from './help.js'
|
||||
import Importer from './importer.js'
|
||||
import Orderable from './orderable.js'
|
||||
import { HTTPError, NOKError, Request, RequestError, ServerRequest } from './request.js'
|
||||
import Rules from './rules.js'
|
||||
import { ServerRequest } from './request.js'
|
||||
import { SCHEMA } from './schema.js'
|
||||
import Share from './share.js'
|
||||
import Slideshow from './slideshow.js'
|
||||
import { SyncEngine } from './sync/engine.js'
|
||||
import Dialog from './ui/dialog.js'
|
||||
import { EditPanel, FullPanel, Panel } from './ui/panel.js'
|
||||
import Tooltip from './ui/tooltip.js'
|
||||
import URLs from './urls.js'
|
||||
import * as Utils from './utils.js'
|
||||
import * as Icon from './rendering/icon.js'
|
||||
import { DataLayer, LAYER_TYPES } from './data/layer.js'
|
||||
import { DataLayerPermissions, MapPermissions } from './permissions.js'
|
||||
import { LAYER_TYPES } from './data/layer.js'
|
||||
import { Point, LineString, Polygon } from './data/features.js'
|
||||
import { LeafletMarker, LeafletPolyline, LeafletPolygon } from './rendering/ui.js'
|
||||
import * as SAVEMANAGER from './saving.js'
|
||||
|
||||
// Import modules and export them to the global scope.
|
||||
// For the not yet module-compatible JS out there.
|
||||
|
@ -39,45 +15,18 @@ import * as SAVEMANAGER from './saving.js'
|
|||
// By alphabetic order
|
||||
window.U = {
|
||||
Alert,
|
||||
AlertCreation,
|
||||
AjaxAutocomplete,
|
||||
AjaxAutocompleteMultiple,
|
||||
AutocompleteDatalist,
|
||||
Browser,
|
||||
Caption,
|
||||
ContextMenu,
|
||||
DataLayer,
|
||||
DataLayerPermissions,
|
||||
Dialog,
|
||||
EditPanel,
|
||||
Facets,
|
||||
Formatter,
|
||||
FullPanel,
|
||||
Help,
|
||||
HTTPError,
|
||||
Icon,
|
||||
Importer,
|
||||
LAYER_TYPES,
|
||||
LeafletMarker,
|
||||
LeafletPolygon,
|
||||
LeafletPolyline,
|
||||
LineString,
|
||||
MapPermissions,
|
||||
NOKError,
|
||||
Orderable,
|
||||
Panel,
|
||||
Point,
|
||||
Polygon,
|
||||
Request,
|
||||
RequestError,
|
||||
Rules,
|
||||
SAVEMANAGER,
|
||||
SCHEMA,
|
||||
ServerRequest,
|
||||
Share,
|
||||
Slideshow,
|
||||
SyncEngine,
|
||||
Tooltip,
|
||||
URLs,
|
||||
Utils,
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { DomEvent, DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
|
||||
import { translate } from './i18n.js'
|
||||
import * as Utils from './utils.js'
|
||||
import Dialog from './ui/dialog.js'
|
||||
|
||||
const SHORTCUTS = {
|
||||
DRAW_MARKER: {
|
||||
|
@ -166,7 +167,7 @@ const ENTRIES = {
|
|||
export default class Help {
|
||||
constructor(umap) {
|
||||
this.umap = umap
|
||||
this.dialog = new U.Dialog({ className: 'dark', accept: false, cancel: false })
|
||||
this.dialog = new Dialog({ className: 'dark', accept: false, cancel: false })
|
||||
this.isMacOS = /mac/i.test(
|
||||
// eslint-disable-next-line compat/compat -- Fallback available.
|
||||
navigator.userAgentData ? navigator.userAgentData.platform : navigator.platform
|
||||
|
|
|
@ -251,7 +251,6 @@ export default class Importer {
|
|||
}
|
||||
|
||||
full() {
|
||||
this.umap._leafletMap.once('postsync', this.umap._leafletMap._setDefaultCenter)
|
||||
try {
|
||||
if (this.files.length) {
|
||||
for (const file of this.files) {
|
||||
|
|
|
@ -193,7 +193,6 @@ export class MapPermissions extends ServerStored {
|
|||
)
|
||||
if (!error) {
|
||||
this.commit()
|
||||
this.umap._leafletMap.fire('postsync')
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import { translate } from '../i18n.js'
|
|||
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
||||
import * as Utils from '../utils.js'
|
||||
import * as Icon from './icon.js'
|
||||
import ContextMenu from '../ui/contextmenu.js'
|
||||
|
||||
// Those options are not saved on the server, so they can live here
|
||||
// instead of in umap.properties
|
||||
|
@ -203,7 +204,7 @@ const ControlsMixin = {
|
|||
</button>
|
||||
`)
|
||||
rightContainer.appendChild(button)
|
||||
const menu = new U.ContextMenu({ className: 'dark', fixed: true })
|
||||
const menu = new ContextMenu({ className: 'dark', fixed: true })
|
||||
const actions = [
|
||||
{
|
||||
label: translate('New map'),
|
||||
|
@ -252,7 +253,7 @@ const ControlsMixin = {
|
|||
})
|
||||
|
||||
const updateConnectedPeersCount = () => {
|
||||
connectedPeersCount.innerHTML = this.sync.getNumberOfConnectedPeers()
|
||||
connectedPeersCount.innerHTML = this.umap.sync.getNumberOfConnectedPeers()
|
||||
}
|
||||
updateConnectedPeersCount()
|
||||
}
|
||||
|
@ -306,8 +307,12 @@ const ControlsMixin = {
|
|||
})
|
||||
},
|
||||
|
||||
initCaptionBar: function () {
|
||||
const container = DomUtil.create('div', 'umap-caption-bar', this._controlContainer)
|
||||
renderCaptionBar: function () {
|
||||
if (this.options.noControl) return
|
||||
const container =
|
||||
this._controlContainer.querySelector('.umap-caption-bar') ||
|
||||
DomUtil.create('div', 'umap-caption-bar', this._controlContainer)
|
||||
container.innerHTML = ''
|
||||
const name = DomUtil.create('h3', 'map-name', container)
|
||||
DomEvent.disableClickPropagation(container)
|
||||
this.umap.addAuthorLink(container)
|
||||
|
@ -316,8 +321,7 @@ const ControlsMixin = {
|
|||
'umap-about-link flat',
|
||||
container,
|
||||
translate('Open caption'),
|
||||
this.umap.openCaption,
|
||||
this
|
||||
() => this.umap.openCaption()
|
||||
)
|
||||
DomUtil.createButton(
|
||||
'umap-open-browser-link flat',
|
||||
|
@ -334,8 +338,8 @@ const ControlsMixin = {
|
|||
)
|
||||
}
|
||||
}
|
||||
this.umap.onceDatalayersLoaded(function () {
|
||||
this.slideshow.renderToolbox(container)
|
||||
this.umap.onceDatalayersLoaded(() => {
|
||||
this.umap.slideshow.renderToolbox(container)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
@ -481,11 +485,18 @@ export const LeafletMap = BaseMap.extend({
|
|||
})
|
||||
},
|
||||
|
||||
attachToDom: function () {
|
||||
setup: function () {
|
||||
this.initControls()
|
||||
// Needs locate control and hash to exist
|
||||
this.initCenter()
|
||||
this.update()
|
||||
},
|
||||
|
||||
update: function () {
|
||||
this.setOptions(this.umap.properties)
|
||||
this.initTileLayers()
|
||||
this.renderCaptionBar()
|
||||
this.renderEditToolbar()
|
||||
// Needs tilelayer to exist for minimap
|
||||
this.renderControls()
|
||||
this.handleLimitBounds()
|
||||
|
|
|
@ -2,6 +2,7 @@ import { DomEvent, DomUtil, stamp } from '../../vendors/leaflet/leaflet-src.esm.
|
|||
import { translate } from './i18n.js'
|
||||
import * as Utils from './utils.js'
|
||||
import { AutocompleteDatalist } from './autocomplete.js'
|
||||
import Orderable from './orderable.js'
|
||||
|
||||
const EMPTY_VALUES = ['', undefined, null]
|
||||
|
||||
|
@ -236,7 +237,7 @@ export default class Rules {
|
|||
rule.renderToolbox(DomUtil.create('li', 'orderable', ul))
|
||||
}
|
||||
|
||||
const orderable = new U.Orderable(ul, this.onReorder.bind(this))
|
||||
const orderable = new Orderable(ul, this.onReorder.bind(this))
|
||||
}
|
||||
|
||||
DomUtil.createButton('umap-add', body, translate('Add rule'), this.addRule, this)
|
||||
|
|
|
@ -83,7 +83,7 @@ export default class Slideshow extends WithTemplate {
|
|||
|
||||
play() {
|
||||
if (this._id) return
|
||||
if (this.umap.editEnabled || !this.umap.options.slideshow.active) return
|
||||
if (this.umap.editEnabled || !this.umap.properties.slideshow.active) return
|
||||
L.DomUtil.addClass(document.body, this.CLASSNAME)
|
||||
this._id = window.setInterval(L.bind(this.loop, this), this.options.delay)
|
||||
this.startSpinner()
|
||||
|
|
|
@ -6,8 +6,8 @@ import { fieldInSchema } from '../utils.js'
|
|||
*/
|
||||
|
||||
class BaseUpdater {
|
||||
constructor(map) {
|
||||
this.map = map
|
||||
constructor(umap) {
|
||||
this.umap = umap
|
||||
}
|
||||
|
||||
updateObjectValue(obj, key, value) {
|
||||
|
@ -32,8 +32,8 @@ class BaseUpdater {
|
|||
}
|
||||
|
||||
getDataLayerFromID(layerId) {
|
||||
if (layerId) return this.map.getDataLayerByUmapId(layerId)
|
||||
return this.map.defaultEditDataLayer()
|
||||
if (layerId) return this.umap.getDataLayerByUmapId(layerId)
|
||||
return this.umap.defaultEditDataLayer()
|
||||
}
|
||||
|
||||
applyMessage(payload) {
|
||||
|
@ -45,18 +45,18 @@ class BaseUpdater {
|
|||
export class MapUpdater extends BaseUpdater {
|
||||
update({ key, value }) {
|
||||
if (fieldInSchema(key)) {
|
||||
this.updateObjectValue(this.map, key, value)
|
||||
this.updateObjectValue(this.umap, key, value)
|
||||
}
|
||||
|
||||
this.map.render([key])
|
||||
this.umap.render([key])
|
||||
}
|
||||
}
|
||||
|
||||
export class DataLayerUpdater extends BaseUpdater {
|
||||
upsert({ value }) {
|
||||
// Inserts does not happen (we use multiple updates instead).
|
||||
this.map.createDataLayer(value, false)
|
||||
this.map.render([])
|
||||
this.umap.createDataLayer(value, false)
|
||||
this.umap.render([])
|
||||
}
|
||||
|
||||
update({ key, metadata, value }) {
|
||||
|
|
|
@ -32,6 +32,7 @@ import {
|
|||
uMapAlertCreation as AlertCreation,
|
||||
uMapAlert as Alert,
|
||||
} from '../components/alerts/alert.js'
|
||||
import Orderable from './orderable.js'
|
||||
|
||||
export default class Umap extends ServerStored {
|
||||
constructor(element, geojson) {
|
||||
|
@ -85,11 +86,16 @@ export default class Umap extends ServerStored {
|
|||
if (center) {
|
||||
this._leafletMap.options.center = this._leafletMap.latLng(center)
|
||||
}
|
||||
this._leafletMap.attachToDom()
|
||||
|
||||
// Needed to render controls
|
||||
this.permissions = new MapPermissions(this)
|
||||
this.urls = new URLs(this.properties.urls)
|
||||
this.slideshow = new Slideshow(this, this.properties.slideshow)
|
||||
|
||||
this._leafletMap.setup()
|
||||
|
||||
if (geojson.properties.schema) this.overrideSchema(geojson.properties.schema)
|
||||
|
||||
this.urls = new URLs(this.properties.urls)
|
||||
|
||||
this.panel = new Panel(this)
|
||||
this.dialog = new Dialog({ className: 'dark' })
|
||||
|
@ -171,15 +177,12 @@ export default class Umap extends ServerStored {
|
|||
await this.loadDataFromQueryString()
|
||||
}
|
||||
|
||||
this.slideshow = new Slideshow(this, this.properties.slideshow)
|
||||
this.permissions = new MapPermissions(this)
|
||||
if (this.hasEditMode()) {
|
||||
this._leafletMap.initEditTools()
|
||||
}
|
||||
|
||||
if (!this.properties.noControl) {
|
||||
this.initShortcuts()
|
||||
this._leafletMap.initCaptionBar()
|
||||
this._leafletMap.on('contextmenu', this.onContextMenu)
|
||||
this.onceDataLoaded(this.setViewFromQueryString)
|
||||
this.propagate()
|
||||
|
@ -1245,7 +1248,7 @@ export default class Umap extends ServerStored {
|
|||
|
||||
render(fields) {
|
||||
if (fields.includes('numberOfConnectedPeers')) {
|
||||
this.renderEditToolbar()
|
||||
this._leafletMap.renderEditToolbar()
|
||||
this.propagate()
|
||||
}
|
||||
|
||||
|
@ -1253,10 +1256,7 @@ export default class Umap extends ServerStored {
|
|||
for (const impact of impacts) {
|
||||
switch (impact) {
|
||||
case 'ui':
|
||||
this._leafletMap.setOptions(this.properties)
|
||||
this._leafletMap.initCaptionBar()
|
||||
this._leafletMap.renderEditToolbar()
|
||||
this._leafletMap.renderControls()
|
||||
this._leafletMap.update()
|
||||
this.browser.redraw()
|
||||
this.propagate()
|
||||
break
|
||||
|
@ -1383,7 +1383,7 @@ export default class Umap extends ServerStored {
|
|||
})
|
||||
this.indexDatalayers()
|
||||
}
|
||||
const orderable = new U.Orderable(ul, onReorder)
|
||||
const orderable = new Orderable(ul, onReorder)
|
||||
|
||||
const bar = DomUtil.create('div', 'button-bar', container)
|
||||
DomUtil.createButton(
|
||||
|
@ -1499,17 +1499,13 @@ export default class Umap extends ServerStored {
|
|||
dataLayer.fromUmapGeoJSON(geojson)
|
||||
}
|
||||
|
||||
// TODO: refactor with leafletMap init / render
|
||||
this._leafletMap.setOptions(this.properties)
|
||||
this._leafletMap.initTileLayers()
|
||||
this._leafletMap.renderControls()
|
||||
this._leafletMap.handleLimitBounds()
|
||||
this._leafletMap.update()
|
||||
this.eachDataLayer((datalayer) => {
|
||||
if (mustReindex) datalayer.reindex()
|
||||
datalayer.redraw()
|
||||
})
|
||||
this.propagate()
|
||||
this._leafletMap.fire('postsync')
|
||||
this._leafletMap._setDefaultCenter()
|
||||
this.isDirty = true
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,10 @@ export function getImpactsFromSchema(fields, schema) {
|
|||
export function fieldInSchema(field, schema) {
|
||||
const current_schema = schema || U.SCHEMA
|
||||
if (typeof field !== 'string') return false
|
||||
const field_name = field.replace('options.', '').split('.')[0]
|
||||
const field_name = field
|
||||
.replace('options.', '')
|
||||
.replace('properties.', '')
|
||||
.split('.')[0]
|
||||
return current_schema[field_name] !== undefined
|
||||
}
|
||||
|
||||
|
|
|
@ -1,215 +0,0 @@
|
|||
L.Map.mergeOptions({
|
||||
overlay: {},
|
||||
datalayers: [],
|
||||
maxZoomLimit: 24,
|
||||
attributionControl: false,
|
||||
editMode: 'advanced',
|
||||
noControl: false, // Do not render any control.
|
||||
name: '',
|
||||
description: '',
|
||||
// When a TileLayer is in TMS mode, it needs -y instead of y.
|
||||
// This is usually handled by the TileLayer instance itself, but
|
||||
// we cannot rely on this because of the y is overriden by Leaflet
|
||||
// See https://github.com/Leaflet/Leaflet/pull/9201
|
||||
// And let's remove this -y when this PR is merged and released.
|
||||
demoTileInfos: { s: 'a', z: 9, x: 265, y: 181, '-y': 181, r: '' },
|
||||
licences: [],
|
||||
licence: '',
|
||||
slideshow: {},
|
||||
clickable: true,
|
||||
permissions: {},
|
||||
featuresHaveOwner: false,
|
||||
})
|
||||
|
||||
U.Map = L.Map.extend({
|
||||
includes: [ControlsMixin],
|
||||
|
||||
initialize: async function (el, geojson) {
|
||||
this.sync_engine = new U.SyncEngine(this)
|
||||
this.sync = this.sync_engine.proxy(this)
|
||||
// Locale name (pt_PT, en_US…)
|
||||
// To be used for Django localization
|
||||
if (geojson.properties.locale) L.setLocale(geojson.properties.locale)
|
||||
|
||||
// Language code (pt-pt, en-us…)
|
||||
// To be used in javascript APIs
|
||||
if (geojson.properties.lang) L.lang = geojson.properties.lang
|
||||
|
||||
this.setOptionsFromQueryString(geojson.properties)
|
||||
// Prevent default creation of controls
|
||||
const zoomControl = geojson.properties.zoomControl
|
||||
const fullscreenControl = geojson.properties.fullscreenControl
|
||||
geojson.properties.zoomControl = false
|
||||
geojson.properties.fullscreenControl = false
|
||||
|
||||
L.Map.prototype.initialize.call(this, el, geojson.properties)
|
||||
|
||||
if (geojson.properties.schema) this.overrideSchema(geojson.properties.schema)
|
||||
|
||||
// After calling parent initialize, as we are doing initCenter our-selves
|
||||
if (geojson.geometry) this.options.center = this.latLng(geojson.geometry)
|
||||
this.urls = new U.URLs(this.options.urls)
|
||||
|
||||
this.panel = new U.Panel(this)
|
||||
this.dialog = new U.Dialog({ className: 'dark' })
|
||||
this.tooltip = new U.Tooltip(this._controlContainer)
|
||||
this.contextmenu = new U.ContextMenu()
|
||||
if (this.hasEditMode()) {
|
||||
this.editPanel = new U.EditPanel(this)
|
||||
this.fullPanel = new U.FullPanel(this)
|
||||
}
|
||||
if (!this.options.noControl) {
|
||||
L.DomEvent.on(document.body, 'dataloading', (e) => this.fire('dataloading', e))
|
||||
L.DomEvent.on(document.body, 'dataload', (e) => this.fire('dataload', e))
|
||||
}
|
||||
this.server = new U.ServerRequest()
|
||||
this.request = new U.Request()
|
||||
|
||||
this.initLoader()
|
||||
this.name = this.options.name
|
||||
this.description = this.options.description
|
||||
this.demoTileInfos = this.options.demoTileInfos
|
||||
this.options.zoomControl = zoomControl !== undefined ? zoomControl : true
|
||||
this.options.fullscreenControl =
|
||||
fullscreenControl !== undefined ? fullscreenControl : true
|
||||
|
||||
this.datalayersFromQueryString = L.Util.queryString('datalayers')
|
||||
if (this.datalayersFromQueryString) {
|
||||
this.datalayersFromQueryString = this.datalayersFromQueryString
|
||||
.toString()
|
||||
.split(',')
|
||||
}
|
||||
|
||||
let editedFeature = null
|
||||
try {
|
||||
Object.defineProperty(this, 'editedFeature', {
|
||||
get: () => editedFeature,
|
||||
set: (feature) => {
|
||||
if (editedFeature && editedFeature !== feature) {
|
||||
editedFeature.endEdit()
|
||||
}
|
||||
editedFeature = feature
|
||||
this.fire('seteditedfeature')
|
||||
},
|
||||
})
|
||||
} catch (e) {
|
||||
// Certainly IE8, which has a limited version of defineProperty
|
||||
}
|
||||
|
||||
// Retrocompat
|
||||
if (this.options.slideshow?.delay && this.options.slideshow.active === undefined) {
|
||||
this.options.slideshow.active = true
|
||||
}
|
||||
if (this.options.advancedFilterKey) {
|
||||
this.options.facetKey = this.options.advancedFilterKey
|
||||
delete this.options.advancedFilterKey
|
||||
}
|
||||
|
||||
// Global storage for retrieving datalayers and features.
|
||||
this.datalayers = {} // All datalayers, including deleted.
|
||||
this.datalayers_index = [] // Datalayers actually on the map and ordered.
|
||||
this.features_index = {}
|
||||
|
||||
// Needed for actions labels
|
||||
this.help = new U.Help(this)
|
||||
|
||||
this.formatter = new U.Formatter(this)
|
||||
|
||||
this.initControls()
|
||||
// Needs locate control and hash to exist
|
||||
this.initCenter()
|
||||
this.initTileLayers()
|
||||
// Needs tilelayer to exist for minimap
|
||||
this.renderControls()
|
||||
this.handleLimitBounds()
|
||||
this.initDataLayers()
|
||||
|
||||
if (this.options.displayCaptionOnLoad) {
|
||||
// Retrocompat
|
||||
if (!this.options.onLoadPanel) {
|
||||
this.options.onLoadPanel = 'caption'
|
||||
}
|
||||
delete this.options.displayCaptionOnLoad
|
||||
}
|
||||
if (this.options.displayDataBrowserOnLoad) {
|
||||
// Retrocompat
|
||||
if (!this.options.onLoadPanel) {
|
||||
this.options.onLoadPanel = 'databrowser'
|
||||
}
|
||||
delete this.options.displayDataBrowserOnLoad
|
||||
}
|
||||
if (this.options.datalayersControl === 'expanded') {
|
||||
if (!this.options.onLoadPanel) {
|
||||
this.options.onLoadPanel = 'datalayers'
|
||||
}
|
||||
delete this.options.datalayersControl
|
||||
}
|
||||
if (this.options.onLoadPanel === 'facet') {
|
||||
this.options.onLoadPanel = 'datafilters'
|
||||
}
|
||||
|
||||
// TODO: remove me when moved to modules
|
||||
// and inheriting from ServerStored
|
||||
try {
|
||||
Object.defineProperty(this, 'isDirty', {
|
||||
get: () => U.SAVEMANAGER.has(this),
|
||||
set: (status) => {
|
||||
if (status) {
|
||||
U.SAVEMANAGER.add(this)
|
||||
} else {
|
||||
U.SAVEMANAGER.remove(this)
|
||||
}
|
||||
},
|
||||
})
|
||||
} catch (e) {
|
||||
// Certainly IE8, which has a limited version of defineProperty
|
||||
}
|
||||
this.on(
|
||||
'baselayerchange',
|
||||
function (e) {
|
||||
if (this._controls.miniMap) this._controls.miniMap.onMainMapBaseLayerChange(e)
|
||||
},
|
||||
this
|
||||
)
|
||||
|
||||
// Creation mode
|
||||
if (!this.options.umap_id) {
|
||||
if (!this.options.preview) {
|
||||
this.isDirty = true
|
||||
this.enableEdit()
|
||||
}
|
||||
this._default_extent = true
|
||||
this.options.name = L._('Untitled map')
|
||||
await this.loadDataFromQueryString()
|
||||
}
|
||||
|
||||
this.slideshow = new U.Slideshow(this, this.options.slideshow)
|
||||
this.permissions = new U.MapPermissions(this)
|
||||
if (this.hasEditMode()) {
|
||||
this.editTools = new U.Editable(this)
|
||||
this.renderEditToolbar()
|
||||
}
|
||||
|
||||
if (!this.options.noControl) {
|
||||
this.initShortcuts()
|
||||
this.initCaptionBar()
|
||||
this.on('contextmenu', this.onContextMenu)
|
||||
this.onceDataLoaded(this.setViewFromQueryString)
|
||||
this.on('click', this.closeInplaceToolbar)
|
||||
this.propagate()
|
||||
}
|
||||
|
||||
window.onbeforeunload = () => (this.editEnabled && U.SAVEMANAGER.isDirty) || null
|
||||
this.backup()
|
||||
},
|
||||
|
||||
|
||||
getFeatureById: function (id) {
|
||||
let feature
|
||||
for (const datalayer of this.datalayers_index) {
|
||||
feature = datalayer.getFeatureById(id)
|
||||
if (feature) return feature
|
||||
}
|
||||
},
|
||||
|
||||
})
|
|
@ -161,7 +161,7 @@ def test_websocket_connection_can_sync_polygons(
|
|||
|
||||
@pytest.mark.xdist_group(name="websockets")
|
||||
def test_websocket_connection_can_sync_map_properties(
|
||||
context, live_server, websocket_server, tilelayer
|
||||
new_page, live_server, websocket_server, tilelayer
|
||||
):
|
||||
map = MapFactory(name="sync", edit_status=Map.ANONYMOUS)
|
||||
map.settings["properties"]["syncEnabled"] = True
|
||||
|
@ -169,9 +169,9 @@ def test_websocket_connection_can_sync_map_properties(
|
|||
DataLayerFactory(map=map, data={})
|
||||
|
||||
# Create two tabs
|
||||
peerA = context.new_page()
|
||||
peerA = new_page()
|
||||
peerA.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
||||
peerB = context.new_page()
|
||||
peerB = new_page()
|
||||
peerB.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
||||
|
||||
# Name change is synced
|
||||
|
@ -193,7 +193,7 @@ def test_websocket_connection_can_sync_map_properties(
|
|||
|
||||
@pytest.mark.xdist_group(name="websockets")
|
||||
def test_websocket_connection_can_sync_datalayer_properties(
|
||||
context, live_server, websocket_server, tilelayer
|
||||
new_page, live_server, websocket_server, tilelayer
|
||||
):
|
||||
map = MapFactory(name="sync", edit_status=Map.ANONYMOUS)
|
||||
map.settings["properties"]["syncEnabled"] = True
|
||||
|
@ -201,9 +201,9 @@ def test_websocket_connection_can_sync_datalayer_properties(
|
|||
DataLayerFactory(map=map, data={})
|
||||
|
||||
# Create two tabs
|
||||
peerA = context.new_page()
|
||||
peerA = new_page()
|
||||
peerA.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
||||
peerB = context.new_page()
|
||||
peerB = new_page()
|
||||
peerB.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
|
||||
|
||||
# Layer addition, name and type are synced
|
||||
|
@ -215,7 +215,7 @@ def test_websocket_connection_can_sync_datalayer_properties(
|
|||
peerA.locator("body").press("Escape")
|
||||
|
||||
peerB.get_by_role("link", name="Manage layers").click()
|
||||
peerB.get_by_role("button", name="Edit").first.click()
|
||||
peerB.locator(".panel.right").get_by_role("button", name="Edit").first.click()
|
||||
expect(peerB.locator('input[name="name"]')).to_have_value("synced layer!")
|
||||
expect(peerB.get_by_role("combobox")).to_have_value("Choropleth")
|
||||
|
||||
|
|
Loading…
Reference in a new issue