umap-project 2.7.3__py3-none-any.whl → 2.8.0a0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. umap/__init__.py +1 -1
  2. umap/forms.py +4 -14
  3. umap/locale/am_ET/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/am_ET/LC_MESSAGES/django.po +278 -151
  5. umap/locale/ar/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/ar/LC_MESSAGES/django.po +335 -141
  7. umap/locale/bg/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/bg/LC_MESSAGES/django.po +279 -152
  9. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  10. umap/locale/br/LC_MESSAGES/django.po +95 -79
  11. umap/locale/ca/LC_MESSAGES/django.mo +0 -0
  12. umap/locale/ca/LC_MESSAGES/django.po +85 -68
  13. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  14. umap/locale/cs_CZ/LC_MESSAGES/django.po +78 -66
  15. umap/locale/da/LC_MESSAGES/django.mo +0 -0
  16. umap/locale/da/LC_MESSAGES/django.po +280 -153
  17. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  18. umap/locale/de/LC_MESSAGES/django.po +80 -64
  19. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  20. umap/locale/el/LC_MESSAGES/django.po +82 -66
  21. umap/locale/en/LC_MESSAGES/django.po +73 -61
  22. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  23. umap/locale/es/LC_MESSAGES/django.po +75 -63
  24. umap/locale/et/LC_MESSAGES/django.mo +0 -0
  25. umap/locale/et/LC_MESSAGES/django.po +280 -153
  26. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  27. umap/locale/eu/LC_MESSAGES/django.po +82 -66
  28. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  29. umap/locale/fa_IR/LC_MESSAGES/django.po +80 -64
  30. umap/locale/fi/LC_MESSAGES/django.mo +0 -0
  31. umap/locale/fi/LC_MESSAGES/django.po +278 -151
  32. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  33. umap/locale/fr/LC_MESSAGES/django.po +75 -63
  34. umap/locale/gl/LC_MESSAGES/django.mo +0 -0
  35. umap/locale/gl/LC_MESSAGES/django.po +280 -153
  36. umap/locale/he/LC_MESSAGES/django.mo +0 -0
  37. umap/locale/he/LC_MESSAGES/django.po +281 -154
  38. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  39. umap/locale/hu/LC_MESSAGES/django.po +80 -64
  40. umap/locale/is/LC_MESSAGES/django.mo +0 -0
  41. umap/locale/is/LC_MESSAGES/django.po +280 -153
  42. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  43. umap/locale/it/LC_MESSAGES/django.po +82 -66
  44. umap/locale/ja/LC_MESSAGES/django.mo +0 -0
  45. umap/locale/ja/LC_MESSAGES/django.po +280 -153
  46. umap/locale/ko/LC_MESSAGES/django.mo +0 -0
  47. umap/locale/ko/LC_MESSAGES/django.po +280 -153
  48. umap/locale/lt/LC_MESSAGES/django.mo +0 -0
  49. umap/locale/lt/LC_MESSAGES/django.po +280 -153
  50. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  51. umap/locale/ms/LC_MESSAGES/django.po +82 -66
  52. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  53. umap/locale/nl/LC_MESSAGES/django.po +280 -153
  54. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  55. umap/locale/pl/LC_MESSAGES/django.po +82 -66
  56. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  57. umap/locale/pt/LC_MESSAGES/django.po +75 -63
  58. umap/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  59. umap/locale/pt_BR/LC_MESSAGES/django.po +280 -153
  60. umap/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  61. umap/locale/pt_PT/LC_MESSAGES/django.po +280 -153
  62. umap/locale/ru/LC_MESSAGES/django.mo +0 -0
  63. umap/locale/ru/LC_MESSAGES/django.po +280 -153
  64. umap/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  65. umap/locale/sk_SK/LC_MESSAGES/django.po +280 -153
  66. umap/locale/sl/LC_MESSAGES/django.mo +0 -0
  67. umap/locale/sl/LC_MESSAGES/django.po +280 -153
  68. umap/locale/sr/LC_MESSAGES/django.mo +0 -0
  69. umap/locale/sr/LC_MESSAGES/django.po +280 -153
  70. umap/locale/sv/LC_MESSAGES/django.mo +0 -0
  71. umap/locale/sv/LC_MESSAGES/django.po +81 -65
  72. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  73. umap/locale/th_TH/LC_MESSAGES/django.po +257 -185
  74. umap/locale/tr/LC_MESSAGES/django.mo +0 -0
  75. umap/locale/tr/LC_MESSAGES/django.po +280 -153
  76. umap/locale/uk_UA/LC_MESSAGES/django.mo +0 -0
  77. umap/locale/uk_UA/LC_MESSAGES/django.po +280 -153
  78. umap/locale/vi/LC_MESSAGES/django.mo +0 -0
  79. umap/locale/vi/LC_MESSAGES/django.po +278 -151
  80. umap/locale/zh/LC_MESSAGES/django.mo +0 -0
  81. umap/locale/zh/LC_MESSAGES/django.po +278 -151
  82. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  83. umap/locale/zh_TW/LC_MESSAGES/django.po +97 -81
  84. umap/management/commands/empty_trash.py +32 -0
  85. umap/management/commands/migrate_to_S3.py +29 -0
  86. umap/migrations/0023_alter_datalayer_uuid.py +19 -0
  87. umap/migrations/0024_alter_map_share_status.py +30 -0
  88. umap/migrations/0025_alter_datalayer_geojson.py +24 -0
  89. umap/models.py +68 -116
  90. umap/settings/base.py +22 -2
  91. umap/static/umap/base.css +3 -603
  92. umap/static/umap/content.css +5 -3
  93. umap/static/umap/css/bar.css +202 -0
  94. umap/static/umap/css/form.css +617 -0
  95. umap/static/umap/css/icon.css +21 -1
  96. umap/static/umap/css/popup.css +125 -0
  97. umap/static/umap/img/16-white.svg +16 -4
  98. umap/static/umap/img/16.svg +1 -1
  99. umap/static/umap/img/source/16-white.svg +46 -45
  100. umap/static/umap/img/source/16.svg +1 -753
  101. umap/static/umap/js/components/fragment.js +3 -1
  102. umap/static/umap/js/modules/browser.js +20 -19
  103. umap/static/umap/js/modules/caption.js +21 -22
  104. umap/static/umap/js/modules/data/features.js +101 -74
  105. umap/static/umap/js/modules/data/layer.js +157 -137
  106. umap/static/umap/js/modules/facets.js +9 -9
  107. umap/static/umap/js/modules/formatter.js +5 -5
  108. umap/static/umap/js/modules/global.js +4 -52
  109. umap/static/umap/js/modules/help.js +18 -21
  110. umap/static/umap/js/modules/importer.js +71 -39
  111. umap/static/umap/js/modules/importers/cadastrefr.js +4 -0
  112. umap/static/umap/js/modules/importers/geodatamine.js +3 -3
  113. umap/static/umap/js/modules/importers/overpass.js +5 -0
  114. umap/static/umap/js/modules/permissions.js +85 -87
  115. umap/static/umap/js/modules/rendering/layers/base.js +15 -15
  116. umap/static/umap/js/modules/rendering/layers/classified.js +1 -1
  117. umap/static/umap/js/modules/rendering/layers/cluster.js +1 -1
  118. umap/static/umap/js/modules/rendering/layers/heat.js +1 -1
  119. umap/static/umap/js/modules/rendering/map.js +390 -0
  120. umap/static/umap/js/modules/rendering/popup.js +10 -9
  121. umap/static/umap/js/modules/rendering/template.js +35 -12
  122. umap/static/umap/js/modules/rendering/ui.js +57 -12
  123. umap/static/umap/js/modules/rules.js +22 -25
  124. umap/static/umap/js/modules/saving.js +47 -0
  125. umap/static/umap/js/modules/schema.js +5 -0
  126. umap/static/umap/js/modules/share.js +21 -24
  127. umap/static/umap/js/modules/slideshow.js +24 -20
  128. umap/static/umap/js/modules/sync/updaters.js +7 -9
  129. umap/static/umap/js/modules/tableeditor.js +20 -19
  130. umap/static/umap/js/modules/ui/bar.js +196 -0
  131. umap/static/umap/js/modules/ui/panel.js +10 -9
  132. umap/static/umap/js/modules/umap.js +1668 -0
  133. umap/static/umap/js/modules/urls.js +2 -2
  134. umap/static/umap/js/modules/utils.js +20 -6
  135. umap/static/umap/js/umap.controls.js +74 -301
  136. umap/static/umap/js/umap.core.js +29 -50
  137. umap/static/umap/js/umap.forms.js +34 -27
  138. umap/static/umap/keycloak.png +0 -0
  139. umap/static/umap/locale/am_ET.js +26 -10
  140. umap/static/umap/locale/am_ET.json +26 -10
  141. umap/static/umap/locale/ar.js +26 -10
  142. umap/static/umap/locale/ar.json +26 -10
  143. umap/static/umap/locale/ast.js +26 -10
  144. umap/static/umap/locale/ast.json +26 -10
  145. umap/static/umap/locale/bg.js +26 -10
  146. umap/static/umap/locale/bg.json +26 -10
  147. umap/static/umap/locale/br.js +27 -20
  148. umap/static/umap/locale/br.json +27 -20
  149. umap/static/umap/locale/ca.js +32 -29
  150. umap/static/umap/locale/ca.json +32 -29
  151. umap/static/umap/locale/cs_CZ.js +24 -17
  152. umap/static/umap/locale/cs_CZ.json +24 -17
  153. umap/static/umap/locale/da.js +26 -10
  154. umap/static/umap/locale/da.json +26 -10
  155. umap/static/umap/locale/de.js +21 -14
  156. umap/static/umap/locale/de.json +21 -14
  157. umap/static/umap/locale/el.js +28 -12
  158. umap/static/umap/locale/el.json +28 -12
  159. umap/static/umap/locale/en.js +12 -9
  160. umap/static/umap/locale/en.json +12 -9
  161. umap/static/umap/locale/en_US.json +26 -10
  162. umap/static/umap/locale/es.js +16 -13
  163. umap/static/umap/locale/es.json +16 -13
  164. umap/static/umap/locale/et.js +26 -10
  165. umap/static/umap/locale/et.json +26 -10
  166. umap/static/umap/locale/eu.js +16 -9
  167. umap/static/umap/locale/eu.json +16 -9
  168. umap/static/umap/locale/fa_IR.js +16 -9
  169. umap/static/umap/locale/fa_IR.json +16 -9
  170. umap/static/umap/locale/fi.js +26 -10
  171. umap/static/umap/locale/fi.json +26 -10
  172. umap/static/umap/locale/fr.js +12 -9
  173. umap/static/umap/locale/fr.json +12 -9
  174. umap/static/umap/locale/gl.js +26 -10
  175. umap/static/umap/locale/gl.json +26 -10
  176. umap/static/umap/locale/he.js +26 -10
  177. umap/static/umap/locale/he.json +26 -10
  178. umap/static/umap/locale/hr.js +26 -10
  179. umap/static/umap/locale/hr.json +26 -10
  180. umap/static/umap/locale/hu.js +16 -9
  181. umap/static/umap/locale/hu.json +16 -9
  182. umap/static/umap/locale/id.js +26 -10
  183. umap/static/umap/locale/id.json +26 -10
  184. umap/static/umap/locale/is.js +26 -10
  185. umap/static/umap/locale/is.json +26 -10
  186. umap/static/umap/locale/it.js +26 -10
  187. umap/static/umap/locale/it.json +26 -10
  188. umap/static/umap/locale/ja.js +26 -10
  189. umap/static/umap/locale/ja.json +26 -10
  190. umap/static/umap/locale/ko.js +26 -10
  191. umap/static/umap/locale/ko.json +26 -10
  192. umap/static/umap/locale/lt.js +26 -10
  193. umap/static/umap/locale/lt.json +26 -10
  194. umap/static/umap/locale/ms.js +28 -12
  195. umap/static/umap/locale/ms.json +28 -12
  196. umap/static/umap/locale/nl.js +28 -12
  197. umap/static/umap/locale/nl.json +28 -12
  198. umap/static/umap/locale/no.js +26 -10
  199. umap/static/umap/locale/no.json +26 -10
  200. umap/static/umap/locale/pl.js +28 -12
  201. umap/static/umap/locale/pl.json +28 -12
  202. umap/static/umap/locale/pl_PL.json +26 -10
  203. umap/static/umap/locale/pt.js +16 -9
  204. umap/static/umap/locale/pt.json +16 -9
  205. umap/static/umap/locale/pt_BR.js +26 -10
  206. umap/static/umap/locale/pt_BR.json +26 -10
  207. umap/static/umap/locale/pt_PT.js +16 -9
  208. umap/static/umap/locale/pt_PT.json +16 -9
  209. umap/static/umap/locale/ro.js +26 -10
  210. umap/static/umap/locale/ro.json +26 -10
  211. umap/static/umap/locale/ru.js +26 -10
  212. umap/static/umap/locale/ru.json +26 -10
  213. umap/static/umap/locale/si.js +7 -7
  214. umap/static/umap/locale/si.json +7 -7
  215. umap/static/umap/locale/sk_SK.js +26 -10
  216. umap/static/umap/locale/sk_SK.json +26 -10
  217. umap/static/umap/locale/sl.js +26 -10
  218. umap/static/umap/locale/sl.json +26 -10
  219. umap/static/umap/locale/sr.js +26 -10
  220. umap/static/umap/locale/sr.json +26 -10
  221. umap/static/umap/locale/sv.js +27 -11
  222. umap/static/umap/locale/sv.json +27 -11
  223. umap/static/umap/locale/th_TH.js +28 -12
  224. umap/static/umap/locale/th_TH.json +28 -12
  225. umap/static/umap/locale/tr.js +26 -10
  226. umap/static/umap/locale/tr.json +26 -10
  227. umap/static/umap/locale/uk_UA.js +26 -10
  228. umap/static/umap/locale/uk_UA.json +26 -10
  229. umap/static/umap/locale/vi.js +26 -10
  230. umap/static/umap/locale/vi.json +26 -10
  231. umap/static/umap/locale/vi_VN.json +26 -10
  232. umap/static/umap/locale/zh.js +26 -10
  233. umap/static/umap/locale/zh.json +26 -10
  234. umap/static/umap/locale/zh_CN.json +26 -10
  235. umap/static/umap/locale/zh_TW.Big5.json +26 -10
  236. umap/static/umap/locale/zh_TW.js +34 -27
  237. umap/static/umap/locale/zh_TW.json +34 -27
  238. umap/static/umap/map.css +5 -364
  239. umap/static/umap/unittests/URLs.js +15 -15
  240. umap/static/umap/unittests/utils.js +23 -1
  241. umap/static/umap/vars.css +2 -0
  242. umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +5 -1
  243. umap/storage.py +152 -0
  244. umap/templates/registration/login.html +7 -6
  245. umap/templates/umap/css.html +3 -0
  246. umap/templates/umap/js.html +1 -2
  247. umap/templates/umap/map_init.html +4 -5
  248. umap/templates/umap/user_dashboard.html +18 -19
  249. umap/tests/base.py +5 -1
  250. umap/tests/integration/conftest.py +2 -1
  251. umap/tests/integration/test_anonymous_owned_map.py +18 -10
  252. umap/tests/integration/test_browser.py +16 -1
  253. umap/tests/integration/test_dashboard.py +1 -1
  254. umap/tests/integration/test_edit_datalayer.py +18 -7
  255. umap/tests/integration/test_import.py +8 -5
  256. umap/tests/integration/test_optimistic_merge.py +31 -8
  257. umap/tests/integration/test_owned_map.py +22 -16
  258. umap/tests/integration/test_popup.py +44 -0
  259. umap/tests/integration/test_save.py +35 -0
  260. umap/tests/integration/test_view_marker.py +12 -0
  261. umap/tests/integration/test_view_polyline.py +257 -0
  262. umap/tests/integration/test_websocket_sync.py +81 -9
  263. umap/tests/test_datalayer.py +6 -7
  264. umap/tests/test_datalayer_s3.py +135 -0
  265. umap/tests/test_datalayer_views.py +28 -10
  266. umap/tests/test_empty_trash.py +34 -0
  267. umap/tests/test_map.py +12 -3
  268. umap/tests/test_map_views.py +69 -37
  269. umap/tests/test_views.py +53 -0
  270. umap/urls.py +3 -3
  271. umap/views.py +107 -76
  272. {umap_project-2.7.3.dist-info → umap_project-2.8.0a0.dist-info}/METADATA +16 -13
  273. {umap_project-2.7.3.dist-info → umap_project-2.8.0a0.dist-info}/RECORD +276 -262
  274. umap/management/commands/purge_purgatory.py +0 -28
  275. umap/static/umap/js/umap.js +0 -1903
  276. umap/tests/test_purge_purgatory.py +0 -25
  277. {umap_project-2.7.3.dist-info → umap_project-2.8.0a0.dist-info}/WHEEL +0 -0
  278. {umap_project-2.7.3.dist-info → umap_project-2.8.0a0.dist-info}/entry_points.txt +0 -0
  279. {umap_project-2.7.3.dist-info → umap_project-2.8.0a0.dist-info}/licenses/LICENSE +0 -0
@@ -2,6 +2,7 @@ import { DomEvent, DomUtil, stamp } from '../../vendors/leaflet/leaflet-src.esm.
2
2
  import { translate } from './i18n.js'
3
3
  import * as Utils from './utils.js'
4
4
  import { AutocompleteDatalist } from './autocomplete.js'
5
+ import Orderable from './orderable.js'
5
6
 
6
7
  const EMPTY_VALUES = ['', undefined, null]
7
8
 
@@ -21,10 +22,10 @@ class Rule {
21
22
 
22
23
  set isDirty(status) {
23
24
  this._isDirty = status
24
- if (status) this.map.isDirty = status
25
+ if (status) this._umap.isDirty = status
25
26
  }
26
27
 
27
- constructor(map, condition = '', options = {}) {
28
+ constructor(umap, condition = '', options = {}) {
28
29
  // TODO make this public properties when browser coverage is ok
29
30
  // cf https://caniuse.com/?search=public%20class%20field
30
31
  this._condition = null
@@ -37,14 +38,14 @@ class Rule {
37
38
  ['!=', this.not_equal],
38
39
  ['=', this.equal],
39
40
  ]
40
- this.map = map
41
+ this._umap = umap
41
42
  this.active = true
42
43
  this.options = options
43
44
  this.condition = condition
44
45
  }
45
46
 
46
47
  render(fields) {
47
- this.map.render(fields)
48
+ this._umap.render(fields)
48
49
  }
49
50
 
50
51
  equal(other) {
@@ -101,10 +102,6 @@ class Rule {
101
102
  return this.operator(this.cast(props[this.key]))
102
103
  }
103
104
 
104
- getMap() {
105
- return this.map
106
- }
107
-
108
105
  getOption(option) {
109
106
  return this.options[option]
110
107
  }
@@ -136,7 +133,7 @@ class Rule {
136
133
  const defaultShapeProperties = DomUtil.add('div', '', container)
137
134
  defaultShapeProperties.appendChild(builder.build())
138
135
  const autocomplete = new AutocompleteDatalist(builder.helpers.condition.input)
139
- const properties = this.map.allProperties()
136
+ const properties = this._umap.allProperties()
140
137
  autocomplete.suggestions = properties
141
138
  autocomplete.input.addEventListener('input', (event) => {
142
139
  const value = event.target.value
@@ -144,12 +141,12 @@ class Rule {
144
141
  autocomplete.suggestions = [`${value}=`, `${value}!=`, `${value}>`, `${value}<`]
145
142
  } else if (value.endsWith('=')) {
146
143
  const key = value.split('!')[0].split('=')[0]
147
- autocomplete.suggestions = this.map
144
+ autocomplete.suggestions = this._umap
148
145
  .sortedValues(key)
149
146
  .map((str) => `${value}${str || ''}`)
150
147
  }
151
148
  })
152
- this.map.editPanel.open({ content: container })
149
+ this._umap.editPanel.open({ content: container })
153
150
  }
154
151
 
155
152
  renderToolbox(row) {
@@ -176,7 +173,7 @@ class Rule {
176
173
  function () {
177
174
  if (!confirm(translate('Are you sure you want to delete this rule?'))) return
178
175
  this._delete()
179
- this.map.editPanel.close()
176
+ this._umap.editPanel.close()
180
177
  },
181
178
  this
182
179
  )
@@ -186,27 +183,27 @@ class Rule {
186
183
  DomEvent.on(toggle, 'click', () => {
187
184
  this.active = !this.active
188
185
  row.classList.toggle('off', !this.active)
189
- this.map.render(['rules'])
186
+ this._umap.render(['rules'])
190
187
  })
191
188
  }
192
189
 
193
190
  _delete() {
194
- this.map.rules.rules = this.map.rules.rules.filter((rule) => rule !== this)
191
+ this._umap.rules.rules = this._umap.rules.rules.filter((rule) => rule !== this)
195
192
  }
196
193
  }
197
194
 
198
195
  export default class Rules {
199
- constructor(map) {
200
- this.map = map
196
+ constructor(umap) {
197
+ this._umap = umap
201
198
  this.rules = []
202
- this.loadRules()
199
+ this.load()
203
200
  }
204
201
 
205
- loadRules() {
206
- if (!this.map.options.rules?.length) return
207
- for (const { condition, options } of this.map.options.rules) {
202
+ load() {
203
+ if (!this._umap.properties.rules?.length) return
204
+ for (const { condition, options } of this._umap.properties.rules) {
208
205
  if (!condition) continue
209
- this.rules.push(new Rule(this.map, condition, options))
206
+ this.rules.push(new Rule(this._umap, condition, options))
210
207
  }
211
208
  }
212
209
 
@@ -225,7 +222,7 @@ export default class Rules {
225
222
  else newIdx = referenceIdx + 1
226
223
  this.rules.splice(newIdx, 0, moved)
227
224
  moved.isDirty = true
228
- this.map.render(['rules'])
225
+ this._umap.render(['rules'])
229
226
  }
230
227
 
231
228
  edit(container) {
@@ -236,21 +233,21 @@ export default class Rules {
236
233
  rule.renderToolbox(DomUtil.create('li', 'orderable', ul))
237
234
  }
238
235
 
239
- const orderable = new U.Orderable(ul, this.onReorder.bind(this))
236
+ const orderable = new Orderable(ul, this.onReorder.bind(this))
240
237
  }
241
238
 
242
239
  DomUtil.createButton('umap-add', body, translate('Add rule'), this.addRule, this)
243
240
  }
244
241
 
245
242
  addRule() {
246
- const rule = new Rule(this.map)
243
+ const rule = new Rule(this._umap)
247
244
  rule.isDirty = true
248
245
  this.rules.push(rule)
249
246
  rule.edit(map)
250
247
  }
251
248
 
252
249
  commit() {
253
- this.map.options.rules = this.rules.map((rule) => {
250
+ this._umap.properties.rules = this.rules.map((rule) => {
254
251
  return {
255
252
  condition: rule.condition,
256
253
  options: rule.options,
@@ -0,0 +1,47 @@
1
+ const _queue = new Set()
2
+
3
+ export let isDirty = false
4
+
5
+ export async function save() {
6
+ for (const obj of _queue) {
7
+ const ok = await obj.save()
8
+ if (!ok) break
9
+ remove(obj)
10
+ }
11
+ }
12
+
13
+ function add(obj) {
14
+ _queue.add(obj)
15
+ onUpdate()
16
+ }
17
+
18
+ function remove(obj) {
19
+ _queue.delete(obj)
20
+ onUpdate()
21
+ }
22
+
23
+ function has(obj) {
24
+ return _queue.has(obj)
25
+ }
26
+
27
+ function onUpdate() {
28
+ isDirty = Boolean(_queue.size)
29
+ document.body.classList.toggle('umap-is-dirty', isDirty)
30
+ }
31
+
32
+ export class ServerStored {
33
+ set isDirty(status) {
34
+ if (status) {
35
+ add(this)
36
+ } else {
37
+ remove(this)
38
+ }
39
+ this.onDirty(status)
40
+ }
41
+
42
+ get isDirty() {
43
+ return has(this)
44
+ }
45
+
46
+ onDirty(status) {}
47
+ }
@@ -563,4 +563,9 @@ export const SCHEMA = {
563
563
  type: Object,
564
564
  impacts: ['data'],
565
565
  },
566
+
567
+ _referenceVersion: {
568
+ type: Number,
569
+ impacts: ['data'],
570
+ },
566
571
  }
@@ -4,8 +4,8 @@ import { translate } from './i18n.js'
4
4
  import * as Utils from './utils.js'
5
5
 
6
6
  export default class Share {
7
- constructor(map) {
8
- this.map = map
7
+ constructor(umap) {
8
+ this._umap = umap
9
9
  }
10
10
 
11
11
  build() {
@@ -22,11 +22,11 @@ export default class Share {
22
22
  window.location.protocol + Utils.getBaseUrl()
23
23
  )
24
24
 
25
- if (this.map.options.shortUrl) {
25
+ if (this._umap.properties.shortUrl) {
26
26
  DomUtil.createCopiableInput(
27
27
  this.container,
28
28
  translate('Short link'),
29
- this.map.options.shortUrl
29
+ this._umap.properties.shortUrl
30
30
  )
31
31
  }
32
32
 
@@ -60,8 +60,8 @@ export default class Share {
60
60
  this.container,
61
61
  translate('All data and settings of the map')
62
62
  )
63
- const downloadUrl = Utils.template(this.map.options.urls.map_download, {
64
- map_id: this.map.options.umap_id,
63
+ const downloadUrl = this._umap.urls.get('map_download', {
64
+ map_id: this._umap.id,
65
65
  })
66
66
  const link = Utils.loadTemplate(`
67
67
  <div>
@@ -115,10 +115,11 @@ export default class Share {
115
115
  'queryString.captionBar',
116
116
  'queryString.captionMenus',
117
117
  ]
118
- for (let i = 0; i < this.map.HIDDABLE_CONTROLS.length; i++) {
119
- UIFields.push(`queryString.${this.map.HIDDABLE_CONTROLS[i]}Control`)
118
+ // TODO: move HIDDABLE_CONTROLS to SCHEMA ?
119
+ for (const name of this._umap._leafletMap.HIDDABLE_CONTROLS) {
120
+ UIFields.push(`queryString.${name}Control`)
120
121
  }
121
- const iframeExporter = new IframeExporter(this.map)
122
+ const iframeExporter = new IframeExporter(this._umap)
122
123
  const buildIframeCode = () => {
123
124
  iframe.textContent = iframeExporter.build()
124
125
  exportUrl.value = window.location.protocol + iframeExporter.buildUrl()
@@ -136,13 +137,13 @@ export default class Share {
136
137
 
137
138
  open() {
138
139
  if (!this.container) this.build()
139
- this.map.panel.open({ content: this.container })
140
+ this._umap.panel.open({ content: this.container })
140
141
  }
141
142
 
142
143
  async format(mode) {
143
144
  const type = EXPORT_FORMATS[mode]
144
- const content = await type.formatter(this.map)
145
- const filename = Utils.slugify(this.map.options.name) + type.ext
145
+ const content = await type.formatter(this._umap)
146
+ const filename = Utils.slugify(this._umap.properties.name) + type.ext
146
147
  return { content, filetype: type.filetype, filename }
147
148
  }
148
149
 
@@ -161,8 +162,8 @@ export default class Share {
161
162
  }
162
163
 
163
164
  class IframeExporter {
164
- constructor(map) {
165
- this.map = map
165
+ constructor(umap) {
166
+ this._umap = umap
166
167
  this.baseUrl = Utils.getBaseUrl()
167
168
  this.options = {
168
169
  includeFullScreenLink: true,
@@ -192,24 +193,20 @@ class IframeExporter {
192
193
  height: '300px',
193
194
  }
194
195
  // Use map default, not generic default
195
- this.queryString.onLoadPanel = this.map.getOption('onLoadPanel')
196
- }
197
-
198
- getMap() {
199
- return this.map
196
+ this.queryString.onLoadPanel = this._umap.getProperty('onLoadPanel')
200
197
  }
201
198
 
202
199
  buildUrl(options) {
203
200
  const datalayers = []
204
- if (this.options.viewCurrentFeature && this.map.currentFeature) {
205
- this.queryString.feature = this.map.currentFeature.getSlug()
201
+ if (this.options.viewCurrentFeature && this._umap.currentFeature) {
202
+ this.queryString.feature = this._umap.currentFeature.getSlug()
206
203
  } else {
207
204
  delete this.queryString.feature
208
205
  }
209
206
  if (this.options.keepCurrentDatalayers) {
210
- this.map.eachDataLayer((datalayer) => {
211
- if (datalayer.isVisible() && datalayer.umap_id) {
212
- datalayers.push(datalayer.umap_id)
207
+ this._umap.eachDataLayer((datalayer) => {
208
+ if (datalayer.isVisible() && datalayer.createdOnServer) {
209
+ datalayers.push(datalayer.id)
213
210
  }
214
211
  })
215
212
  this.queryString.datalayers = datalayers.join(',')
@@ -13,26 +13,22 @@ const TOOLBOX_TEMPLATE = `
13
13
  `
14
14
 
15
15
  export default class Slideshow extends WithTemplate {
16
- constructor(map, options) {
16
+ constructor(umap, leafletMap, properties) {
17
17
  super()
18
- this.map = map
18
+ this._umap = umap
19
19
  this._id = null
20
20
  this.CLASSNAME = 'umap-slideshow-active'
21
- this.setOptions(options)
21
+ this.load()
22
22
  this._current = null
23
23
 
24
- if (this.options.autoplay) {
25
- this.map.onceDataLoaded(function () {
24
+ if (this.properties.autoplay) {
25
+ this._umap.onceDataLoaded(function () {
26
26
  this.play()
27
27
  }, this)
28
28
  }
29
- this.map.on(
30
- 'edit:enabled',
31
- function () {
32
- this.stop()
33
- },
34
- this
35
- )
29
+ leafletMap.on('edit:enabled', () => {
30
+ this.stop()
31
+ })
36
32
  }
37
33
 
38
34
  set current(feature) {
@@ -54,22 +50,26 @@ export default class Slideshow extends WithTemplate {
54
50
  return this.current.getNext()
55
51
  }
56
52
 
57
- setOptions(options) {
58
- this.options = Object.assign(
53
+ load() {
54
+ this.setProperties(this._umap.properties.slideshow)
55
+ }
56
+
57
+ setProperties(properties = {}) {
58
+ this.properties = Object.assign(
59
59
  {
60
60
  delay: 5000,
61
61
  autoplay: false,
62
62
  },
63
- options
63
+ properties
64
64
  )
65
65
  }
66
66
 
67
67
  defaultDatalayer() {
68
- return this.map.findDataLayer((d) => d.canBrowse())
68
+ return this._umap.findDataLayer((d) => d.canBrowse())
69
69
  }
70
70
 
71
71
  startSpinner() {
72
- const time = Number.parseInt(this.options.delay, 10)
72
+ const time = Number.parseInt(this.properties.delay, 10)
73
73
  if (!time) return
74
74
  const css = `rotation ${time / 1000}s infinite linear`
75
75
  const spinner = document.querySelector('.umap-slideshow-toolbox .play .spinner')
@@ -81,11 +81,15 @@ export default class Slideshow extends WithTemplate {
81
81
  spinner.style.animation = 'none'
82
82
  }
83
83
 
84
+ isEnabled() {
85
+ return Boolean(this.properties.active)
86
+ }
87
+
84
88
  play() {
85
89
  if (this._id) return
86
- if (this.map.editEnabled || !this.map.options.slideshow.active) return
90
+ if (this._umap.editEnabled || !this.isEnabled()) return
87
91
  L.DomUtil.addClass(document.body, this.CLASSNAME)
88
- this._id = window.setInterval(L.bind(this.loop, this), this.options.delay)
92
+ this._id = window.setInterval(L.bind(this.loop, this), this.properties.delay)
89
93
  this.startSpinner()
90
94
  this.loop()
91
95
  }
@@ -123,7 +127,7 @@ export default class Slideshow extends WithTemplate {
123
127
 
124
128
  step() {
125
129
  if (!this.current) return this.stop()
126
- this.current.zoomTo({ easing: this.options.easing })
130
+ this.current.zoomTo({ easing: this.properties.easing })
127
131
  this.current.view()
128
132
  }
129
133
 
@@ -6,8 +6,8 @@ import { fieldInSchema } from '../utils.js'
6
6
  */
7
7
 
8
8
  class BaseUpdater {
9
- constructor(map) {
10
- this.map = map
9
+ constructor(umap) {
10
+ this._umap = umap
11
11
  }
12
12
 
13
13
  updateObjectValue(obj, key, value) {
@@ -32,8 +32,7 @@ class BaseUpdater {
32
32
  }
33
33
 
34
34
  getDataLayerFromID(layerId) {
35
- if (layerId) return this.map.getDataLayerByUmapId(layerId)
36
- return this.map.defaultEditDataLayer()
35
+ return this._umap.getDataLayerByUmapId(layerId)
37
36
  }
38
37
 
39
38
  applyMessage(payload) {
@@ -45,18 +44,17 @@ class BaseUpdater {
45
44
  export class MapUpdater extends BaseUpdater {
46
45
  update({ key, value }) {
47
46
  if (fieldInSchema(key)) {
48
- this.updateObjectValue(this.map, key, value)
47
+ this.updateObjectValue(this._umap, key, value)
49
48
  }
50
49
 
51
- this.map.render([key])
50
+ this._umap.render([key])
52
51
  }
53
52
  }
54
53
 
55
54
  export class DataLayerUpdater extends BaseUpdater {
56
55
  upsert({ value }) {
57
- // Inserts does not happen (we use multiple updates instead).
58
- this.map.createDataLayer(value, false)
59
- this.map.render([])
56
+ // Upsert only happens when a new datalayer is created.
57
+ this._umap.createDataLayer(value, false)
60
58
  }
61
59
 
62
60
  update({ key, metadata, value }) {
@@ -14,10 +14,11 @@ const TEMPLATE = `
14
14
  `
15
15
 
16
16
  export default class TableEditor extends WithTemplate {
17
- constructor(datalayer) {
17
+ constructor(umap, datalayer, leafletMap) {
18
18
  super()
19
19
  this.datalayer = datalayer
20
- this.map = this.datalayer.map
20
+ this._umap = umap
21
+ this._leafletMap = leafletMap
21
22
  this.contextmenu = new ContextMenu({ className: 'dark' })
22
23
  this.table = this.loadTemplate(TEMPLATE)
23
24
  if (!this.datalayer.isRemoteLayer()) {
@@ -36,20 +37,20 @@ export default class TableEditor extends WithTemplate {
36
37
  openHeaderMenu(property) {
37
38
  const actions = []
38
39
  let filterItem
39
- if (this.map.facets.has(property)) {
40
+ if (this._umap.facets.has(property)) {
40
41
  filterItem = {
41
42
  label: translate('Remove filter for this column'),
42
43
  action: () => {
43
- this.map.facets.remove(property)
44
- this.map.browser.open('filters')
44
+ this._umap.facets.remove(property)
45
+ this._umap.browser.open('filters')
45
46
  },
46
47
  }
47
48
  } else {
48
49
  filterItem = {
49
50
  label: translate('Add filter for this column'),
50
51
  action: () => {
51
- this.map.facets.add(property)
52
- this.map.browser.open('filters')
52
+ this._umap.facets.add(property)
53
+ this._umap.browser.open('filters')
53
54
  },
54
55
  }
55
56
  }
@@ -86,8 +87,8 @@ export default class TableEditor extends WithTemplate {
86
87
  }
87
88
 
88
89
  renderBody() {
89
- const bounds = this.map.getBounds()
90
- const inBbox = this.map.browser.options.inBbox
90
+ const bounds = this._leafletMap.getBounds()
91
+ const inBbox = this._umap.browser.options.inBbox
91
92
  let html = ''
92
93
  this.datalayer.eachFeature((feature) => {
93
94
  if (feature.isFiltered()) return
@@ -104,7 +105,7 @@ export default class TableEditor extends WithTemplate {
104
105
  resetProperties() {
105
106
  this.properties = this.datalayer._propertiesIndex
106
107
  if (this.properties.length === 0) {
107
- this.properties = ['name', 'description']
108
+ this.properties = [U.DEFAULT_LABEL_KEY, 'description']
108
109
  }
109
110
  }
110
111
 
@@ -121,7 +122,7 @@ export default class TableEditor extends WithTemplate {
121
122
  }
122
123
 
123
124
  renameProperty(property) {
124
- this.map.dialog
125
+ this._umap.dialog
125
126
  .prompt(translate('Please enter the new name of this property'))
126
127
  .then(({ prompt }) => {
127
128
  if (!prompt || !this.validateName(prompt)) return
@@ -135,7 +136,7 @@ export default class TableEditor extends WithTemplate {
135
136
  }
136
137
 
137
138
  deleteProperty(property) {
138
- this.map.dialog
139
+ this._umap.dialog
139
140
  .confirm(
140
141
  translate('Are you sure you want to delete this property on all the features?')
141
142
  )
@@ -150,7 +151,7 @@ export default class TableEditor extends WithTemplate {
150
151
  }
151
152
 
152
153
  addProperty() {
153
- this.map.dialog
154
+ this._umap.dialog
154
155
  .prompt(translate('Please enter the name of the property'))
155
156
  .then(({ prompt }) => {
156
157
  if (!prompt || !this.validateName(prompt)) return
@@ -187,10 +188,10 @@ export default class TableEditor extends WithTemplate {
187
188
  <button class="flat" type="button" data-ref="filters">
188
189
  <i class="icon icon-16 icon-filters"></i>${translate('Filter data')}
189
190
  </button>`)
190
- filterButton.addEventListener('click', () => this.map.browser.open('filters'))
191
+ filterButton.addEventListener('click', () => this._umap.browser.open('filters'))
191
192
  actions.push(filterButton)
192
193
 
193
- this.map.fullPanel.open({
194
+ this._umap.fullPanel.open({
194
195
  content: this.table,
195
196
  className: 'umap-table-editor',
196
197
  actions: actions,
@@ -304,7 +305,7 @@ export default class TableEditor extends WithTemplate {
304
305
  deleteRows() {
305
306
  const selectedRows = this.getSelectedRows()
306
307
  if (!selectedRows.length) return
307
- this.map.dialog
308
+ this._umap.dialog
308
309
  .confirm(
309
310
  translate('Found {count} rows. Are you sure you want to delete all?', {
310
311
  count: selectedRows.length,
@@ -320,9 +321,9 @@ export default class TableEditor extends WithTemplate {
320
321
  this.datalayer.show()
321
322
  this.datalayer.dataChanged()
322
323
  this.renderBody()
323
- if (this.map.browser.isOpen()) {
324
- this.map.browser.resetFilters()
325
- this.map.browser.open('filters')
324
+ if (this._umap.browser.isOpen()) {
325
+ this._umap.browser.resetFilters()
326
+ this._umap.browser.open('filters')
326
327
  }
327
328
  })
328
329
  }