Compare commits

..

5 commits

Author SHA1 Message Date
Yohan Boniface
51e41b7bce chore: remove unused imports from global.js 2024-11-12 15:28:05 +01:00
Yohan Boniface
b49f3d7633 chore: remove old umap.js file 2024-11-12 15:06:34 +01:00
Yohan Boniface
0dbac92853 chore: remove 'postsync' event 2024-11-12 14:50:08 +01:00
Yohan Boniface
6d56bbb5de chore: refactore LeafletMap.setup/update 2024-11-12 14:36:59 +01:00
Yohan Boniface
e1a24b6180 chore: fix updaters to use umap instead of map and properties instead of options 2024-11-12 13:27:29 +01:00
12 changed files with 61 additions and 317 deletions

View file

@ -1,37 +1,13 @@
import { import { uMapAlert as Alert } from '../components/alerts/alert.js'
uMapAlert as Alert, import { AjaxAutocomplete, AjaxAutocompleteMultiple } from './autocomplete.js'
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 Help from './help.js' import Help from './help.js'
import Importer from './importer.js' import { ServerRequest } from './request.js'
import Orderable from './orderable.js'
import { HTTPError, NOKError, Request, RequestError, ServerRequest } from './request.js'
import Rules from './rules.js'
import { SCHEMA } from './schema.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 Utils from './utils.js'
import * as Icon from './rendering/icon.js' import * as Icon from './rendering/icon.js'
import { DataLayer, LAYER_TYPES } from './data/layer.js' import { LAYER_TYPES } from './data/layer.js'
import { DataLayerPermissions, MapPermissions } from './permissions.js'
import { Point, LineString, Polygon } from './data/features.js' import { Point, LineString, Polygon } from './data/features.js'
import { LeafletMarker, LeafletPolyline, LeafletPolygon } from './rendering/ui.js' import { LeafletMarker, LeafletPolyline, LeafletPolygon } from './rendering/ui.js'
import * as SAVEMANAGER from './saving.js'
// Import modules and export them to the global scope. // Import modules and export them to the global scope.
// For the not yet module-compatible JS out there. // For the not yet module-compatible JS out there.
@ -39,45 +15,18 @@ import * as SAVEMANAGER from './saving.js'
// By alphabetic order // By alphabetic order
window.U = { window.U = {
Alert, Alert,
AlertCreation,
AjaxAutocomplete, AjaxAutocomplete,
AjaxAutocompleteMultiple, AjaxAutocompleteMultiple,
AutocompleteDatalist,
Browser,
Caption,
ContextMenu,
DataLayer,
DataLayerPermissions,
Dialog,
EditPanel,
Facets,
Formatter,
FullPanel,
Help, Help,
HTTPError,
Icon, Icon,
Importer,
LAYER_TYPES, LAYER_TYPES,
LeafletMarker, LeafletMarker,
LeafletPolygon, LeafletPolygon,
LeafletPolyline, LeafletPolyline,
LineString, LineString,
MapPermissions,
NOKError,
Orderable,
Panel,
Point, Point,
Polygon, Polygon,
Request,
RequestError,
Rules,
SAVEMANAGER,
SCHEMA, SCHEMA,
ServerRequest, ServerRequest,
Share,
Slideshow,
SyncEngine,
Tooltip,
URLs,
Utils, Utils,
} }

View file

@ -1,6 +1,7 @@
import { DomEvent, DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js' import { DomEvent, DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
import { translate } from './i18n.js' import { translate } from './i18n.js'
import * as Utils from './utils.js' import * as Utils from './utils.js'
import Dialog from './ui/dialog.js'
const SHORTCUTS = { const SHORTCUTS = {
DRAW_MARKER: { DRAW_MARKER: {
@ -166,7 +167,7 @@ const ENTRIES = {
export default class Help { export default class Help {
constructor(umap) { constructor(umap) {
this.umap = 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( this.isMacOS = /mac/i.test(
// eslint-disable-next-line compat/compat -- Fallback available. // eslint-disable-next-line compat/compat -- Fallback available.
navigator.userAgentData ? navigator.userAgentData.platform : navigator.platform navigator.userAgentData ? navigator.userAgentData.platform : navigator.platform

View file

@ -251,7 +251,6 @@ export default class Importer {
} }
full() { full() {
this.umap._leafletMap.once('postsync', this.umap._leafletMap._setDefaultCenter)
try { try {
if (this.files.length) { if (this.files.length) {
for (const file of this.files) { for (const file of this.files) {

View file

@ -193,7 +193,6 @@ export class MapPermissions extends ServerStored {
) )
if (!error) { if (!error) {
this.commit() this.commit()
this.umap._leafletMap.fire('postsync')
return true return true
} }
} }

View file

@ -12,6 +12,7 @@ import { translate } from '../i18n.js'
import { uMapAlert as Alert } from '../../components/alerts/alert.js' import { uMapAlert as Alert } from '../../components/alerts/alert.js'
import * as Utils from '../utils.js' import * as Utils from '../utils.js'
import * as Icon from './icon.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 // Those options are not saved on the server, so they can live here
// instead of in umap.properties // instead of in umap.properties
@ -203,7 +204,7 @@ const ControlsMixin = {
</button> </button>
`) `)
rightContainer.appendChild(button) rightContainer.appendChild(button)
const menu = new U.ContextMenu({ className: 'dark', fixed: true }) const menu = new ContextMenu({ className: 'dark', fixed: true })
const actions = [ const actions = [
{ {
label: translate('New map'), label: translate('New map'),
@ -252,7 +253,7 @@ const ControlsMixin = {
}) })
const updateConnectedPeersCount = () => { const updateConnectedPeersCount = () => {
connectedPeersCount.innerHTML = this.sync.getNumberOfConnectedPeers() connectedPeersCount.innerHTML = this.umap.sync.getNumberOfConnectedPeers()
} }
updateConnectedPeersCount() updateConnectedPeersCount()
} }
@ -306,8 +307,12 @@ const ControlsMixin = {
}) })
}, },
initCaptionBar: function () { renderCaptionBar: function () {
const container = DomUtil.create('div', 'umap-caption-bar', this._controlContainer) 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) const name = DomUtil.create('h3', 'map-name', container)
DomEvent.disableClickPropagation(container) DomEvent.disableClickPropagation(container)
this.umap.addAuthorLink(container) this.umap.addAuthorLink(container)
@ -316,8 +321,7 @@ const ControlsMixin = {
'umap-about-link flat', 'umap-about-link flat',
container, container,
translate('Open caption'), translate('Open caption'),
this.umap.openCaption, () => this.umap.openCaption()
this
) )
DomUtil.createButton( DomUtil.createButton(
'umap-open-browser-link flat', 'umap-open-browser-link flat',
@ -334,8 +338,8 @@ const ControlsMixin = {
) )
} }
} }
this.umap.onceDatalayersLoaded(function () { this.umap.onceDatalayersLoaded(() => {
this.slideshow.renderToolbox(container) this.umap.slideshow.renderToolbox(container)
}) })
}, },
} }
@ -481,11 +485,18 @@ export const LeafletMap = BaseMap.extend({
}) })
}, },
attachToDom: function () { setup: function () {
this.initControls() this.initControls()
// Needs locate control and hash to exist // Needs locate control and hash to exist
this.initCenter() this.initCenter()
this.update()
},
update: function () {
this.setOptions(this.umap.properties)
this.initTileLayers() this.initTileLayers()
this.renderCaptionBar()
this.renderEditToolbar()
// Needs tilelayer to exist for minimap // Needs tilelayer to exist for minimap
this.renderControls() this.renderControls()
this.handleLimitBounds() this.handleLimitBounds()

View file

@ -2,6 +2,7 @@ import { DomEvent, DomUtil, stamp } from '../../vendors/leaflet/leaflet-src.esm.
import { translate } from './i18n.js' import { translate } from './i18n.js'
import * as Utils from './utils.js' import * as Utils from './utils.js'
import { AutocompleteDatalist } from './autocomplete.js' import { AutocompleteDatalist } from './autocomplete.js'
import Orderable from './orderable.js'
const EMPTY_VALUES = ['', undefined, null] const EMPTY_VALUES = ['', undefined, null]
@ -236,7 +237,7 @@ export default class Rules {
rule.renderToolbox(DomUtil.create('li', 'orderable', ul)) 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) DomUtil.createButton('umap-add', body, translate('Add rule'), this.addRule, this)

View file

@ -83,7 +83,7 @@ export default class Slideshow extends WithTemplate {
play() { play() {
if (this._id) return 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) L.DomUtil.addClass(document.body, this.CLASSNAME)
this._id = window.setInterval(L.bind(this.loop, this), this.options.delay) this._id = window.setInterval(L.bind(this.loop, this), this.options.delay)
this.startSpinner() this.startSpinner()

View file

@ -6,8 +6,8 @@ import { fieldInSchema } from '../utils.js'
*/ */
class BaseUpdater { class BaseUpdater {
constructor(map) { constructor(umap) {
this.map = map this.umap = umap
} }
updateObjectValue(obj, key, value) { updateObjectValue(obj, key, value) {
@ -32,8 +32,8 @@ class BaseUpdater {
} }
getDataLayerFromID(layerId) { getDataLayerFromID(layerId) {
if (layerId) return this.map.getDataLayerByUmapId(layerId) if (layerId) return this.umap.getDataLayerByUmapId(layerId)
return this.map.defaultEditDataLayer() return this.umap.defaultEditDataLayer()
} }
applyMessage(payload) { applyMessage(payload) {
@ -45,18 +45,18 @@ class BaseUpdater {
export class MapUpdater extends BaseUpdater { export class MapUpdater extends BaseUpdater {
update({ key, value }) { update({ key, value }) {
if (fieldInSchema(key)) { 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 { export class DataLayerUpdater extends BaseUpdater {
upsert({ value }) { upsert({ value }) {
// Inserts does not happen (we use multiple updates instead). // Inserts does not happen (we use multiple updates instead).
this.map.createDataLayer(value, false) this.umap.createDataLayer(value, false)
this.map.render([]) this.umap.render([])
} }
update({ key, metadata, value }) { update({ key, metadata, value }) {

View file

@ -32,6 +32,7 @@ import {
uMapAlertCreation as AlertCreation, uMapAlertCreation as AlertCreation,
uMapAlert as Alert, uMapAlert as Alert,
} from '../components/alerts/alert.js' } from '../components/alerts/alert.js'
import Orderable from './orderable.js'
export default class Umap extends ServerStored { export default class Umap extends ServerStored {
constructor(element, geojson) { constructor(element, geojson) {
@ -85,11 +86,16 @@ export default class Umap extends ServerStored {
if (center) { if (center) {
this._leafletMap.options.center = this._leafletMap.latLng(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) if (geojson.properties.schema) this.overrideSchema(geojson.properties.schema)
this.urls = new URLs(this.properties.urls)
this.panel = new Panel(this) this.panel = new Panel(this)
this.dialog = new Dialog({ className: 'dark' }) this.dialog = new Dialog({ className: 'dark' })
@ -171,15 +177,12 @@ export default class Umap extends ServerStored {
await this.loadDataFromQueryString() await this.loadDataFromQueryString()
} }
this.slideshow = new Slideshow(this, this.properties.slideshow)
this.permissions = new MapPermissions(this)
if (this.hasEditMode()) { if (this.hasEditMode()) {
this._leafletMap.initEditTools() this._leafletMap.initEditTools()
} }
if (!this.properties.noControl) { if (!this.properties.noControl) {
this.initShortcuts() this.initShortcuts()
this._leafletMap.initCaptionBar()
this._leafletMap.on('contextmenu', this.onContextMenu) this._leafletMap.on('contextmenu', this.onContextMenu)
this.onceDataLoaded(this.setViewFromQueryString) this.onceDataLoaded(this.setViewFromQueryString)
this.propagate() this.propagate()
@ -1245,7 +1248,7 @@ export default class Umap extends ServerStored {
render(fields) { render(fields) {
if (fields.includes('numberOfConnectedPeers')) { if (fields.includes('numberOfConnectedPeers')) {
this.renderEditToolbar() this._leafletMap.renderEditToolbar()
this.propagate() this.propagate()
} }
@ -1253,10 +1256,7 @@ export default class Umap extends ServerStored {
for (const impact of impacts) { for (const impact of impacts) {
switch (impact) { switch (impact) {
case 'ui': case 'ui':
this._leafletMap.setOptions(this.properties) this._leafletMap.update()
this._leafletMap.initCaptionBar()
this._leafletMap.renderEditToolbar()
this._leafletMap.renderControls()
this.browser.redraw() this.browser.redraw()
this.propagate() this.propagate()
break break
@ -1383,7 +1383,7 @@ export default class Umap extends ServerStored {
}) })
this.indexDatalayers() this.indexDatalayers()
} }
const orderable = new U.Orderable(ul, onReorder) const orderable = new Orderable(ul, onReorder)
const bar = DomUtil.create('div', 'button-bar', container) const bar = DomUtil.create('div', 'button-bar', container)
DomUtil.createButton( DomUtil.createButton(
@ -1499,17 +1499,13 @@ export default class Umap extends ServerStored {
dataLayer.fromUmapGeoJSON(geojson) dataLayer.fromUmapGeoJSON(geojson)
} }
// TODO: refactor with leafletMap init / render this._leafletMap.update()
this._leafletMap.setOptions(this.properties)
this._leafletMap.initTileLayers()
this._leafletMap.renderControls()
this._leafletMap.handleLimitBounds()
this.eachDataLayer((datalayer) => { this.eachDataLayer((datalayer) => {
if (mustReindex) datalayer.reindex() if (mustReindex) datalayer.reindex()
datalayer.redraw() datalayer.redraw()
}) })
this.propagate() this.propagate()
this._leafletMap.fire('postsync') this._leafletMap._setDefaultCenter()
this.isDirty = true this.isDirty = true
} }

View file

@ -66,7 +66,10 @@ export function getImpactsFromSchema(fields, schema) {
export function fieldInSchema(field, schema) { export function fieldInSchema(field, schema) {
const current_schema = schema || U.SCHEMA const current_schema = schema || U.SCHEMA
if (typeof field !== 'string') return false 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 return current_schema[field_name] !== undefined
} }

View file

@ -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
}
},
})

View file

@ -161,7 +161,7 @@ def test_websocket_connection_can_sync_polygons(
@pytest.mark.xdist_group(name="websockets") @pytest.mark.xdist_group(name="websockets")
def test_websocket_connection_can_sync_map_properties( 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 = MapFactory(name="sync", edit_status=Map.ANONYMOUS)
map.settings["properties"]["syncEnabled"] = True map.settings["properties"]["syncEnabled"] = True
@ -169,9 +169,9 @@ def test_websocket_connection_can_sync_map_properties(
DataLayerFactory(map=map, data={}) DataLayerFactory(map=map, data={})
# Create two tabs # Create two tabs
peerA = context.new_page() peerA = new_page()
peerA.goto(f"{live_server.url}{map.get_absolute_url()}?edit") 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") peerB.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
# Name change is synced # Name change is synced
@ -193,7 +193,7 @@ def test_websocket_connection_can_sync_map_properties(
@pytest.mark.xdist_group(name="websockets") @pytest.mark.xdist_group(name="websockets")
def test_websocket_connection_can_sync_datalayer_properties( 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 = MapFactory(name="sync", edit_status=Map.ANONYMOUS)
map.settings["properties"]["syncEnabled"] = True map.settings["properties"]["syncEnabled"] = True
@ -201,9 +201,9 @@ def test_websocket_connection_can_sync_datalayer_properties(
DataLayerFactory(map=map, data={}) DataLayerFactory(map=map, data={})
# Create two tabs # Create two tabs
peerA = context.new_page() peerA = new_page()
peerA.goto(f"{live_server.url}{map.get_absolute_url()}?edit") 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") peerB.goto(f"{live_server.url}{map.get_absolute_url()}?edit")
# Layer addition, name and type are synced # Layer addition, name and type are synced
@ -215,7 +215,7 @@ def test_websocket_connection_can_sync_datalayer_properties(
peerA.locator("body").press("Escape") peerA.locator("body").press("Escape")
peerB.get_by_role("link", name="Manage layers").click() 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.locator('input[name="name"]')).to_have_value("synced layer!")
expect(peerB.get_by_role("combobox")).to_have_value("Choropleth") expect(peerB.get_by_role("combobox")).to_have_value("Choropleth")