Commit graph

1255 commits

Author SHA1 Message Date
David Larlet
6cb1be1fd4
chore: use direct import for ServerRequest in alerts 2024-06-12 18:03:05 -04:00
David Larlet
ddaafa8cda
chore: scroll when the help box is too big 2024-06-12 18:03:05 -04:00
David Larlet
c0ecc39439
chore: uniformize buttons across panels and alerts 2024-06-12 18:03:05 -04:00
David Larlet
e1f91b393d
chore: do not display zoom alert on save 2024-06-12 18:03:05 -04:00
David Larlet
6bbdec49bf
chore: refactor web components with templates 2024-06-12 18:03:04 -04:00
David Larlet
6f715c109b
chore: improve message/choice in case of conflicts 2024-06-12 18:03:04 -04:00
David Larlet
5c2528900e
chore: Use web components to display alerts + a11y roles 2024-06-12 18:03:04 -04:00
Yohan Boniface
8967ab5901 whore: prettier 2024-06-11 14:12:33 +02:00
Yohan Boniface
50ef073d36
Merge pull request #1883 from umap-project/remove-u-keys
chore: remove U.Keys, and refactor global shorcuts
2024-06-07 18:35:49 +02:00
f42498d195 refactor(sync): Sync layers creation with map.createDataLayer utility.
Rather than having it done inside the datalayer itself. This gives us
more control.
2024-06-07 18:21:30 +02:00
149a0c1680 refactor: rename geometrytoFeatures to geoJSONToLeaflet
Because we are dealing with technologies using overlapping vocabulary,
it is easy to get lost. Hopefully this change makes it clear that it
converts geoJSON inputs in Leaflet / uMap objects.
2024-06-07 18:21:30 +02:00
137cc21af2 feat(sync): Add a proxy to the SyncEngine objects.
It is now possible to create proxy objects using `sync_engine.proxy(object)`.
The returned proxy object will automatically inject `metadata` and
`subject` parameters, after looking for them in the `getSyncMetadata`
method (these are only known to the synced objects).

As a result, the calls are now simplified:

```
this.sync.update("key", "value")
```
2024-06-07 18:21:30 +02:00
4e7ac23b53 refactor(sync): remove formbuilder this._redraw() callbacks.
They are now handled in the `render()` call, so there is no more need
for them here.
2024-06-07 18:21:30 +02:00
5247bf77d3 refactor(sync): Remove syncUpdateProperties function.
The function was only used once, so removing it  simplified the whole
flow.
2024-06-07 18:21:30 +02:00
d3730a99ff fix: use array.includes(string) the proper way.
Because this `syncUpdatedProperties` function is only called once, it
didn't trigger any issue in practice (as the check was always returning
true).
2024-06-07 18:21:30 +02:00
90780fbf6d fixup: changes after @ybon's review. 2024-06-07 18:21:30 +02:00
50b7188647 fix(sync): sync the reference-version across peers
This allows the merge algorithm to not be lost when receiving changes.
Without this change, the optimistic merge algorithm isn't able to make
the distinction between peers, and features end up duplicated.
2024-06-07 18:21:30 +02:00
b1a4053b2e chore(sync): remove belongsTo for now
As it requires more discussion, it will happen in a separate
pull-request.
2024-06-07 18:21:30 +02:00
bc1dec245b chore(sync): Sync engine now retrieves auth token
It's now it's responsability to get the authentication token from
the http server and pass it to the websocket server, it will make it
possible to redo the roundtrip when getting disconnected.
2024-06-07 18:21:30 +02:00
82ede035d6 chore(sync): use sync=false everywhere to stop propagation
In some cases, you want to stop the propagation of events. The previous
code was using `fromSync=true` and `sync=false` interchangeably. This
makes it use `sync=false` everywhere.
2024-06-07 18:21:30 +02:00
637ab67b93 chore(utils): remove console.log calls 2024-06-07 18:21:30 +02:00
5a565dd2ee fix(schema): dashArray belongs to features as well 2024-06-07 18:21:30 +02:00
92676e03ae chore(sync): Add message-dispatcher unit tests 2024-06-07 18:21:30 +02:00
74a1670c9d feat(sync): Add JS unittests for updateObjectValue, and refactor.
The new implementation uses `reduce`, in the hopes of producing a more
readable version than old-style loops and reassignment of object values.
2024-06-07 18:21:30 +02:00
80eaa151de refactor(sync): Remove unnecessary complexity
Because we're relying on the `geoJSONToFeatures` method, we don't need
anymore updaters, the default ones (map, datalayer, feature) are enough.

It also makes the codebase compatible with our eslint configuration.
2024-06-07 18:21:30 +02:00
9e36476abe chore(sync) make the test pass 2024-06-07 18:21:30 +02:00
d5bff22081 fix(sync) only send datalayer options 2024-06-07 18:21:30 +02:00
898a3e93b2 fix(sync): do not call getSyncMetadata if it doesn't exist
This can arise when the form isn't bound to a "syncable" object. We
might want to provide an utility to check an object is *syncable*, or a
specific form to not attempt to sync objects which don't need it.
2024-06-07 18:21:30 +02:00
8e5c434988 feat(sync): Allow the sync of datalayer creation 2024-06-07 18:21:30 +02:00
458d68a4bb fix(sync): allow features geometries to be synced
By defining the `geometry` property in the schema.
2024-06-07 18:21:30 +02:00
01408254c9 fix(sync): intialize the sync engine before entering edit mode.
Otherwise `this.sync` is not defined.
2024-06-07 18:21:30 +02:00
46207741ff feat(sync): handle syncing of map limitbounds. 2024-06-07 18:21:30 +02:00
9cb87392c0 feat(sync): Avoid syncing remote datalayers' features
They will be synced on their own, and we dont want them to be present
twice on the map.
2024-06-07 18:21:30 +02:00
b99c242648 fix(sync): Initialize tilelayerand remoteData earlier.
It makes it possible to set these values on a remote peer.
2024-06-07 18:21:30 +02:00
059103b66c fix(sync): Allow overlays to sync
`this.options.overlay` is now set during `map.initialize()`, which makes
it possible to be set by incoming websocket operations.
2024-06-07 18:21:30 +02:00
2fafad714e chore(sync): Ensure properties can be updated before doing it.
When receiving a message, this checks the given properties belong to
the "subject" before applying the message.
2024-06-07 18:21:30 +02:00
25ccdde0b0 chore(schema): Add a belongsTo field in the schema.
The goal is to use this as a security measure, to check that the
updated properties belong the the "subject" when receiving sync
operations.
2024-06-07 18:21:30 +02:00
28a359e03f fix(sync): Allow cloning of features
Removing the `id` from the feature when cloning makes it generate a new
one. Without this change, the cloned feature keep the already existing
`id`, and during sync, the original object is lost (replaced by the
clone).

Nobody wants to be replaced by a clone.
2024-06-07 18:21:30 +02:00
e4bcb53c6f feat(sync): Sync only when the edition of a feature is over.
It's less spectacular than sending the position as it changes, but takes
less bandwidth and seems good enough.
2024-06-07 18:21:30 +02:00
ce0f3c9d3e fix(sync): Import the data when syncing GeoJSON objects.
Prior to these changes, the data wasn't transmitted over WebSocket, and
even if present it wasn't taken into account.
2024-06-07 18:21:30 +02:00
e24173eb9f fix(sync): Keep features IDs for Polygons and Lines
It wasn't passed previously, so objects where duplicated.
2024-06-07 18:21:30 +02:00
c6ee25b906 feat(sync): Only sync when on edit mode
The is done to save server resources, for accessed maps which
aren't currently being edited.
2024-06-07 18:21:30 +02:00
66eb90ffd1 chore(sync): Move the sync flag in the options
The goal being for it to be hidden for now.

- Add a `is_owner` method on the map and use it in the view
- Remove duplicated line in `global.js`
- Rename `Datalayer` to `DataLayer` everywhere
- Move the sync flag in the map options (next to slideshow)
2024-06-07 18:21:30 +02:00
32a4f3feda feat(sync): Add WebSocket specific settings
`WEBSOCKET_ENABLED`, `WEBSOCKET_HOST`, `WEBSOCKET_PORT` and
`WEBSOCKET_URI` have been added.

They are being transmitted to the client via the `map.options`.
When `WEBSOCKET_ENABLED` is set to `False`, the client doesn't have
the ability to be synced.
2024-06-07 18:21:30 +02:00
5e692d2280 feat(sync): Add a enableSync option.
This changes how the syncEngine works. At the moment, it's always
instanciated, even if no syncing is configured. It just does nothing.

This is to avoid doing `if (engine) engine.update()` calls everywhere
we use it.

You now need to `start()` and `stop()` it.
2024-06-07 18:21:30 +02:00
9a74cc370c feat(sync): initialize datalayers internal objects in the constructor.
Otherwise, an event can come from the websocket, trying to update an
`undefined` property.
2024-06-07 18:21:30 +02:00
b956101d5d feat(sync): sync layer's properties.
This also changes the interface between the synced classes and the sync
engine.

The sync engines only requires two methods now:

- `getSyncMetadata()` which returns all the metadata needed, including
the `engine`.
- `render()` which renders the object, updating the needed parts.
2024-06-07 18:21:30 +02:00
66105127cb feat(sync): Sync features over websockets
Added a new `geometryToFeature` method in `umap.layer.js` which can
update a given geometry if needed.

A new `id` property can also be passed to the features on creation, to
make it possible to have the same features `id` on different peers.
2024-06-07 18:21:30 +02:00
c9abb15dd1 feat(sync): sync map properties over websocket
All keystrokes are currently sent, which is not ideal because it will
use a lot of bandwidth.
2024-06-07 18:21:30 +02:00
698c926997 feat(sync): sync features and map properties
Synced objects now expose different methods, such as:
- `getSyncEngine` which returns the location of the sync object.
- `getMetadata` which returns the associated metadata with the object.

Hooks have been added when features are created or changed, so the
changes can be synced with other peers.
2024-06-07 18:21:30 +02:00