@kalisio/kdk 2.5.3 → 2.6.0

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 (545) hide show
  1. package/.github/workflows/main.yaml +35 -6
  2. package/client.globe.js +8 -0
  3. package/client.js +8 -0
  4. package/client.map.js +8 -0
  5. package/core/api/hooks/hooks.push.js +3 -2
  6. package/core/api/hooks/hooks.tags.js +56 -0
  7. package/core/api/models/tags.model.mongodb.js +8 -0
  8. package/core/api/services/index.js +33 -2
  9. package/core/api/services/tags/tags.hooks.js +47 -0
  10. package/core/client/api.js +5 -5
  11. package/core/client/components/KActivity.vue +3 -2
  12. package/core/client/components/KChip.vue +2 -2
  13. package/core/client/components/KEditor.vue +3 -1
  14. package/core/client/components/KFollower.vue +4 -4
  15. package/core/client/components/KStore.vue +1 -1
  16. package/core/client/components/KTab.vue +20 -7
  17. package/core/client/components/account/KProfile.vue +9 -25
  18. package/core/client/components/action/KAction.vue +10 -10
  19. package/core/client/components/action/KToggleFullscreenAction.vue +2 -11
  20. package/core/client/components/app/KHome.vue +3 -2
  21. package/core/client/components/collection/KFilter.vue +5 -4
  22. package/core/client/components/collection/KGrid.vue +5 -1
  23. package/core/client/components/collection/KItemsFilter.vue +47 -0
  24. package/core/client/components/collection/KItemsSorter.vue +42 -0
  25. package/core/client/components/collection/KScrollDown.vue +2 -2
  26. package/core/client/components/collection/KSearchFilterControl.vue +3 -2
  27. package/core/client/components/collection/KSorter.vue +33 -37
  28. package/core/client/components/collection/KTagsFilterControl.vue +14 -40
  29. package/core/client/components/collection/KTagsFilterView.vue +10 -45
  30. package/core/client/components/collection/KTimeFilterControl.vue +6 -7
  31. package/core/client/components/collection/KTimeFilterView.vue +13 -22
  32. package/core/client/components/collection/KTimeLine.vue +18 -9
  33. package/core/client/components/form/KColorField.vue +13 -6
  34. package/core/client/components/form/KColorScaleField.vue +7 -12
  35. package/core/client/components/form/KFileField.vue +118 -89
  36. package/core/client/components/form/KForm.vue +30 -18
  37. package/core/client/components/form/KIconField.vue +4 -1
  38. package/core/client/components/form/KNumberField.vue +9 -2
  39. package/core/client/components/form/KSelectField.vue +1 -4
  40. package/core/client/components/form/KTagField.vue +229 -0
  41. package/core/client/components/form/KTextField.vue +4 -0
  42. package/core/client/components/form/KTextareaField.vue +3 -1
  43. package/core/client/components/input/KShapePicker.vue +3 -3
  44. package/core/client/components/layout/KFab.vue +32 -20
  45. package/core/client/components/layout/KPage.vue +11 -6
  46. package/core/client/components/layout/KWindow.vue +5 -0
  47. package/core/client/components/media/index.js +2 -6
  48. package/core/client/components/menu/KMenu.vue +12 -10
  49. package/core/client/components/menu/KSubMenu.vue +12 -12
  50. package/core/client/components/messages/KMessageCard.vue +13 -12
  51. package/core/client/components/messages/KMessageComposer.vue +13 -9
  52. package/core/client/components/messages/KMessagesTimeLine.vue +16 -8
  53. package/core/client/components/tags/KTagFilter.vue +99 -0
  54. package/core/client/components/tags/KTagItem.vue +65 -0
  55. package/core/client/components/tags/KTagManager.vue +198 -0
  56. package/core/client/components/tags/KTagSelection.vue +82 -0
  57. package/core/client/components/time/KDate.vue +3 -17
  58. package/core/client/components/time/KDateTime.vue +1 -1
  59. package/core/client/components/time/KTime.vue +0 -4
  60. package/core/client/composables/collection-filter.js +41 -2
  61. package/core/client/composables/collection.js +3 -3
  62. package/core/client/composables/index.js +1 -0
  63. package/core/client/composables/pwa.js +13 -0
  64. package/core/client/composables/session.js +7 -8
  65. package/core/client/composables/user.js +36 -0
  66. package/core/client/directives/index.js +1 -0
  67. package/core/client/directives/v-drop-file.js +174 -0
  68. package/core/client/document.js +2 -1
  69. package/core/client/exporter.js +17 -3
  70. package/core/client/i18n/core_en.json +34 -7
  71. package/core/client/i18n/core_fr.json +36 -9
  72. package/core/client/i18n.js +26 -11
  73. package/core/client/layout.js +5 -5
  74. package/core/client/mixins/mixin.base-activity.js +8 -5
  75. package/core/client/mixins/mixin.base-editor.js +2 -1
  76. package/core/client/mixins/mixin.base-field.js +3 -2
  77. package/core/client/mixins/mixin.base-item.js +12 -10
  78. package/core/client/mixins/mixin.service.js +3 -1
  79. package/core/client/platform.js +0 -3
  80. package/core/client/readers/reader.json.js +2 -2
  81. package/core/client/utils/index.js +2 -0
  82. package/core/client/utils/utils.collection.js +6 -6
  83. package/core/client/utils/utils.colors.js +46 -19
  84. package/core/client/utils/utils.files.js +19 -0
  85. package/core/client/utils/utils.locale.js +13 -17
  86. package/core/client/utils/utils.services.js +27 -0
  87. package/core/client/utils/utils.shapes.js +2 -2
  88. package/core/client/utils/utils.tags.js +17 -0
  89. package/core/client/utils/utils.tours.js +31 -0
  90. package/core/common/permissions.js +3 -0
  91. package/core/common/schemas/tags.update.json +35 -0
  92. package/core/common/schemas/users.update-profile.json +1 -1
  93. package/core/common/utils.js +5 -5
  94. package/extras/configs/panes.top.js +11 -0
  95. package/extras/configs/stickies.js +1 -1
  96. package/extras/configs/widgets.left.js +13 -1
  97. package/extras/libs/jsts.min.js +8 -0
  98. package/{test/client/core/account.js → extras/tests/core/account.mjs} +4 -4
  99. package/extras/tests/core/api.mjs +114 -0
  100. package/{test/client/core/collection.js → extras/tests/core/collection.mjs} +8 -8
  101. package/{test/client/core/dialogs.js → extras/tests/core/dialogs.mjs} +1 -1
  102. package/extras/tests/core/index.mjs +9 -0
  103. package/{test/client/core/layout.js → extras/tests/core/layout.mjs} +7 -3
  104. package/{test/client/core/runner.js → extras/tests/core/runner.mjs} +3 -3
  105. package/{test/client/core/screens.js → extras/tests/core/screens.mjs} +1 -1
  106. package/{test/client/core/utils.js → extras/tests/core/utils.mjs} +79 -26
  107. package/extras/tests/index.mjs +4 -0
  108. package/{test/client/map/api.js → extras/tests/map/api.mjs} +1 -1
  109. package/{test/client/map/catalog.js → extras/tests/map/catalog.mjs} +18 -18
  110. package/{test/client/map/controls.js → extras/tests/map/controls.mjs} +3 -3
  111. package/extras/tests/map/index.mjs +5 -0
  112. package/{test/client/map/time.js → extras/tests/map/time.mjs} +3 -3
  113. package/{test/client/map/utils.js → extras/tests/map/utils.mjs} +6 -5
  114. package/extras/tours/fab.js +36 -0
  115. package/extras/tours/layout.js +49 -0
  116. package/extras/tours/pane.left.js +78 -0
  117. package/extras/tours/pane.right.js +145 -0
  118. package/extras/tours/pane.top.js +239 -0
  119. package/map/api/config/layers.cjs +28 -13
  120. package/map/api/hooks/hooks.query.js +12 -7
  121. package/map/api/models/catalog.model.mongodb.js +17 -6
  122. package/map/api/services/catalog/catalog.hooks.js +1 -1
  123. package/map/api/services/index.js +18 -1
  124. package/map/client/cesium/utils/utils.cesium.js +25 -65
  125. package/map/client/cesium/utils/utils.features.js +1 -0
  126. package/map/client/cesium/utils/utils.geojson.js +1 -0
  127. package/map/client/cesium/utils/utils.style.js +7 -6
  128. package/map/client/components/KFeatureEditor.vue +3 -3
  129. package/map/client/components/KFeaturesChart.vue +4 -4
  130. package/map/client/components/KFeaturesFilterEditor.vue +19 -13
  131. package/map/client/components/KFeaturesFilterManager.vue +7 -4
  132. package/map/client/components/KFeaturesTable.vue +2 -2
  133. package/map/client/components/KLayerEditor.vue +6 -6
  134. package/map/client/components/KMeasureTool.vue +2 -1
  135. package/map/client/components/catalog/KBaseLayersSelector.vue +1 -1
  136. package/map/client/components/catalog/KCategoryItem.vue +15 -1
  137. package/map/client/components/catalog/KConnectLayer.vue +2 -2
  138. package/map/client/components/catalog/KCreateView.vue +3 -2
  139. package/map/client/components/catalog/KFilteredLayerItem.vue +26 -6
  140. package/map/client/components/catalog/KImportLayer.vue +6 -3
  141. package/map/client/components/catalog/KLayerCategories.vue +6 -6
  142. package/map/client/components/catalog/KLayerItem.vue +12 -2
  143. package/map/client/components/catalog/KLayersList.vue +180 -0
  144. package/map/client/components/catalog/KLayersPanel.vue +146 -36
  145. package/map/client/components/catalog/KLayersSelector.vue +96 -48
  146. package/map/client/components/catalog/KProjectEditor.vue +0 -9
  147. package/map/client/components/catalog/KProjectSelector.vue +3 -2
  148. package/map/client/components/catalog/KProjectsPanel.vue +23 -8
  149. package/map/client/components/catalog/KViewsPanel.vue +18 -8
  150. package/map/client/components/catalog/KWeatherLayersSelector.vue +3 -3
  151. package/map/client/components/form/KDirectionField.vue +3 -6
  152. package/map/client/components/form/KLayerCategoryField.vue +2 -2
  153. package/map/client/components/form/KOwsServiceField.vue +25 -24
  154. package/map/client/components/form/KSelectLayersField.vue +4 -4
  155. package/map/client/components/form/KSelectViewsField.vue +4 -4
  156. package/map/client/components/legend/KLayerLegend.vue +11 -2
  157. package/map/client/components/legend/KLegend.vue +44 -51
  158. package/map/client/components/location/KLocationCardSection.vue +6 -7
  159. package/map/client/components/location/KLocationMap.vue +23 -13
  160. package/map/client/components/stickies/KPosition.vue +5 -0
  161. package/map/client/components/styles/KLayerStyleAction.vue +59 -12
  162. package/map/client/components/styles/KStyleEditor.vue +71 -8
  163. package/map/client/components/styles/KStyleEditorSection.vue +82 -33
  164. package/map/client/components/styles/KStyleManager.vue +119 -59
  165. package/map/client/components/styles/KStylePreview.vue +9 -25
  166. package/map/client/components/styles/KStylePreviewItem.vue +22 -1
  167. package/map/client/components/tools/KSearchTool.vue +1 -1
  168. package/map/client/components/widget/KElevationProfile.vue +20 -17
  169. package/map/client/components/widget/KInformationBox.vue +5 -5
  170. package/map/client/components/widget/KMapillaryViewer.vue +2 -1
  171. package/map/client/components/widget/KTimeSeries.vue +11 -9
  172. package/map/client/globe.js +2 -0
  173. package/map/client/i18n/map_en.json +29 -7
  174. package/map/client/i18n/map_fr.json +29 -7
  175. package/map/client/leaflet/GradientPath.js +61 -24
  176. package/map/client/leaflet/ShapeMarker.js +12 -5
  177. package/map/client/leaflet/TiledMeshLayer.js +3 -3
  178. package/map/client/leaflet/utils/utils.geojson.js +66 -8
  179. package/map/client/leaflet/utils/utils.style.js +14 -15
  180. package/map/client/mixins/globe/mixin.base-globe.js +181 -34
  181. package/map/client/mixins/globe/mixin.file-layers.js +3 -0
  182. package/map/client/mixins/globe/mixin.geojson-layers.js +179 -31
  183. package/map/client/mixins/globe/mixin.opendap-layers.js +2 -1
  184. package/map/client/mixins/globe/mixin.style.js +23 -1
  185. package/map/client/mixins/globe/mixin.tooltip.js +14 -2
  186. package/map/client/mixins/map/mixin.base-map.js +146 -58
  187. package/map/client/mixins/map/mixin.edit-layers.js +18 -15
  188. package/map/client/mixins/map/mixin.geojson-layers.js +181 -106
  189. package/map/client/mixins/map/mixin.heatmap-layers.js +3 -2
  190. package/map/client/mixins/map/mixin.map-activity.js +6 -1
  191. package/map/client/mixins/map/mixin.mapillary-layers.js +2 -1
  192. package/map/client/mixins/map/mixin.pmtiles-layers.js +3 -3
  193. package/map/client/mixins/map/mixin.tiled-mesh-layers.js +3 -2
  194. package/map/client/mixins/map/mixin.tiled-wind-layers.js +3 -2
  195. package/map/client/mixins/mixin.activity.js +197 -51
  196. package/map/client/mixins/mixin.context.js +11 -11
  197. package/map/client/mixins/mixin.feature-service.js +11 -9
  198. package/map/client/mixins/mixin.weacast.js +5 -3
  199. package/map/client/readers/reader.geojson.js +3 -1
  200. package/map/client/utils/utils.capture.js +3 -3
  201. package/map/client/utils/utils.catalog.js +9 -5
  202. package/map/client/utils/utils.features.js +120 -54
  203. package/map/client/utils/utils.js +25 -10
  204. package/map/client/utils/utils.layers.js +148 -24
  205. package/map/client/utils/utils.location.js +26 -9
  206. package/map/client/utils/utils.schema.js +2 -1
  207. package/map/client/utils/utils.style.js +53 -9
  208. package/map/common/geotiff-grid-source.js +1 -3
  209. package/map/common/opendap-utils.js +0 -1
  210. package/map/common/tms-utils.js +0 -1
  211. package/map/common/wcs-utils.js +0 -1
  212. package/map/common/wfs-utils.js +0 -1
  213. package/map/common/wms-utils.js +7 -1
  214. package/map/common/wmts-utils.js +0 -1
  215. package/package.json +12 -12
  216. package/scripts/init_runner.sh +3 -3
  217. package/scripts/kash/CHANGELOG.md +27 -0
  218. package/scripts/kash/kash.sh +556 -237
  219. package/scripts/kash/scripts/run_tests.sh +44 -5
  220. package/scripts/setup_workspace.sh +23 -13
  221. package/test/api/core/config/default.cjs +2 -1
  222. package/test/api/core/tags.test.js +62 -0
  223. package/test/api/map/config/default.cjs +2 -1
  224. package/test/api/map/config/layers.json +9 -0
  225. package/test/api/map/data/openradiation.json +13811 -0
  226. package/test/api/map/grid-sources.test.js +1 -3
  227. package/test/api/map/index.test.js +60 -1
  228. package/test/api/map/style.test.js +30 -1
  229. package/test.api.js +1 -1
  230. package/vite/App.vue +18 -0
  231. package/vite/AppWithGlobe.vue +84 -0
  232. package/vite/GlobeActivity.vue +58 -0
  233. package/vite/MapActivity.vue +63 -0
  234. package/vite/MapActivityWithGlobe.vue +63 -0
  235. package/vite/README.md +169 -0
  236. package/vite/config.js +221 -0
  237. package/vite/index_with_globe.html +50 -0
  238. package/vite/index_with_map.html +50 -0
  239. package/vite/package.json +173 -0
  240. package/vite/quasar.variables.scss +17 -0
  241. package/vite/vite.config.js +166 -0
  242. package/vite/yarn.lock +11641 -0
  243. package/core/client/components/media/KImageViewer.vue +0 -68
  244. package/core/client/components/media/KMarkdownViewer.vue +0 -55
  245. package/core/client/components/media/KMediaBrowser.vue +0 -301
  246. package/coverage/base.css +0 -224
  247. package/coverage/block-navigation.js +0 -87
  248. package/coverage/core/api/application.js.html +0 -1870
  249. package/coverage/core/api/authentication.js.html +0 -874
  250. package/coverage/core/api/db.js.html +0 -793
  251. package/coverage/core/api/hooks/hooks.authentication.js.html +0 -139
  252. package/coverage/core/api/hooks/hooks.authorisations.js.html +0 -958
  253. package/coverage/core/api/hooks/hooks.groups.js.html +0 -229
  254. package/coverage/core/api/hooks/hooks.logger.js.html +0 -163
  255. package/coverage/core/api/hooks/hooks.model.js.html +0 -967
  256. package/coverage/core/api/hooks/hooks.organisations.js.html +0 -541
  257. package/coverage/core/api/hooks/hooks.push.js.html +0 -265
  258. package/coverage/core/api/hooks/hooks.query.js.html +0 -862
  259. package/coverage/core/api/hooks/hooks.schemas.js.html +0 -298
  260. package/coverage/core/api/hooks/hooks.service.js.html +0 -319
  261. package/coverage/core/api/hooks/hooks.storage.js.html +0 -193
  262. package/coverage/core/api/hooks/hooks.users.js.html +0 -595
  263. package/coverage/core/api/hooks/index.html +0 -266
  264. package/coverage/core/api/hooks/index.js.html +0 -115
  265. package/coverage/core/api/index.html +0 -176
  266. package/coverage/core/api/index.js.html +0 -148
  267. package/coverage/core/api/marshall.js.html +0 -448
  268. package/coverage/core/api/models/groups.model.mongodb.js.html +0 -109
  269. package/coverage/core/api/models/index.html +0 -131
  270. package/coverage/core/api/models/messages.model.mongodb.js.html +0 -121
  271. package/coverage/core/api/models/organisations.model.mongodb.js.html +0 -94
  272. package/coverage/core/api/models/tags.model.mongodb.js.html +0 -115
  273. package/coverage/core/api/models/users.model.mongodb.js.html +0 -115
  274. package/coverage/core/api/services/account/account.hooks.js.html +0 -208
  275. package/coverage/core/api/services/account/account.service.js.html +0 -436
  276. package/coverage/core/api/services/account/index.html +0 -131
  277. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +0 -184
  278. package/coverage/core/api/services/authorisations/authorisations.service.js.html +0 -520
  279. package/coverage/core/api/services/authorisations/index.html +0 -131
  280. package/coverage/core/api/services/databases/databases.hooks.js.html +0 -193
  281. package/coverage/core/api/services/databases/databases.service.js.html +0 -100
  282. package/coverage/core/api/services/databases/index.html +0 -131
  283. package/coverage/core/api/services/groups/groups.hooks.js.html +0 -178
  284. package/coverage/core/api/services/groups/index.html +0 -116
  285. package/coverage/core/api/services/import-export/import-export.hooks.js.html +0 -184
  286. package/coverage/core/api/services/import-export/import-export.service.js.html +0 -118
  287. package/coverage/core/api/services/import-export/index.html +0 -131
  288. package/coverage/core/api/services/index.html +0 -116
  289. package/coverage/core/api/services/index.js.html +0 -532
  290. package/coverage/core/api/services/mailer/index.html +0 -131
  291. package/coverage/core/api/services/mailer/mailer.hooks.js.html +0 -190
  292. package/coverage/core/api/services/mailer/mailer.service.js.html +0 -118
  293. package/coverage/core/api/services/messages/index.html +0 -116
  294. package/coverage/core/api/services/messages/messages.hooks.js.html +0 -202
  295. package/coverage/core/api/services/organisations/index.html +0 -131
  296. package/coverage/core/api/services/organisations/organisations.hooks.js.html +0 -178
  297. package/coverage/core/api/services/organisations/organisations.service.js.html +0 -343
  298. package/coverage/core/api/services/push/index.html +0 -131
  299. package/coverage/core/api/services/push/push.hooks.js.html +0 -190
  300. package/coverage/core/api/services/push/push.service.js.html +0 -121
  301. package/coverage/core/api/services/storage/index.html +0 -131
  302. package/coverage/core/api/services/storage/storage.hooks.js.html +0 -190
  303. package/coverage/core/api/services/storage/storage.service.js.html +0 -172
  304. package/coverage/core/api/services/tags/index.html +0 -116
  305. package/coverage/core/api/services/tags/tags.hooks.js.html +0 -178
  306. package/coverage/core/api/services/users/index.html +0 -131
  307. package/coverage/core/api/services/users/users.hooks.js.html +0 -310
  308. package/coverage/core/api/services/users/users.service.js.html +0 -100
  309. package/coverage/core/api/utils.js.html +0 -118
  310. package/coverage/core/common/errors.js.html +0 -88
  311. package/coverage/core/common/index.html +0 -191
  312. package/coverage/core/common/index.js.html +0 -115
  313. package/coverage/core/common/permissions.js.html +0 -733
  314. package/coverage/core/common/schema.js.html +0 -190
  315. package/coverage/core/common/utils.js.html +0 -226
  316. package/coverage/core/common/utils.offline.js.html +0 -199
  317. package/coverage/favicon.png +0 -0
  318. package/coverage/index.html +0 -476
  319. package/coverage/lcov-report/base.css +0 -224
  320. package/coverage/lcov-report/block-navigation.js +0 -87
  321. package/coverage/lcov-report/core/api/application.js.html +0 -1870
  322. package/coverage/lcov-report/core/api/authentication.js.html +0 -874
  323. package/coverage/lcov-report/core/api/db.js.html +0 -793
  324. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +0 -139
  325. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +0 -958
  326. package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +0 -229
  327. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +0 -163
  328. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +0 -967
  329. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +0 -541
  330. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +0 -265
  331. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +0 -862
  332. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +0 -298
  333. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +0 -319
  334. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +0 -193
  335. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +0 -595
  336. package/coverage/lcov-report/core/api/hooks/index.html +0 -266
  337. package/coverage/lcov-report/core/api/hooks/index.js.html +0 -115
  338. package/coverage/lcov-report/core/api/index.html +0 -176
  339. package/coverage/lcov-report/core/api/index.js.html +0 -148
  340. package/coverage/lcov-report/core/api/marshall.js.html +0 -448
  341. package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +0 -109
  342. package/coverage/lcov-report/core/api/models/index.html +0 -131
  343. package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +0 -121
  344. package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +0 -94
  345. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +0 -115
  346. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +0 -115
  347. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +0 -208
  348. package/coverage/lcov-report/core/api/services/account/account.service.js.html +0 -436
  349. package/coverage/lcov-report/core/api/services/account/index.html +0 -131
  350. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +0 -184
  351. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +0 -520
  352. package/coverage/lcov-report/core/api/services/authorisations/index.html +0 -131
  353. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +0 -193
  354. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +0 -100
  355. package/coverage/lcov-report/core/api/services/databases/index.html +0 -131
  356. package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +0 -178
  357. package/coverage/lcov-report/core/api/services/groups/index.html +0 -116
  358. package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +0 -184
  359. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +0 -118
  360. package/coverage/lcov-report/core/api/services/import-export/index.html +0 -131
  361. package/coverage/lcov-report/core/api/services/index.html +0 -116
  362. package/coverage/lcov-report/core/api/services/index.js.html +0 -532
  363. package/coverage/lcov-report/core/api/services/mailer/index.html +0 -131
  364. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +0 -190
  365. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +0 -118
  366. package/coverage/lcov-report/core/api/services/messages/index.html +0 -116
  367. package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +0 -202
  368. package/coverage/lcov-report/core/api/services/organisations/index.html +0 -131
  369. package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +0 -178
  370. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +0 -343
  371. package/coverage/lcov-report/core/api/services/push/index.html +0 -131
  372. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +0 -190
  373. package/coverage/lcov-report/core/api/services/push/push.service.js.html +0 -121
  374. package/coverage/lcov-report/core/api/services/storage/index.html +0 -131
  375. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +0 -190
  376. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +0 -172
  377. package/coverage/lcov-report/core/api/services/tags/index.html +0 -116
  378. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +0 -178
  379. package/coverage/lcov-report/core/api/services/users/index.html +0 -131
  380. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +0 -310
  381. package/coverage/lcov-report/core/api/services/users/users.service.js.html +0 -100
  382. package/coverage/lcov-report/core/api/utils.js.html +0 -118
  383. package/coverage/lcov-report/core/common/errors.js.html +0 -88
  384. package/coverage/lcov-report/core/common/index.html +0 -191
  385. package/coverage/lcov-report/core/common/index.js.html +0 -115
  386. package/coverage/lcov-report/core/common/permissions.js.html +0 -733
  387. package/coverage/lcov-report/core/common/schema.js.html +0 -190
  388. package/coverage/lcov-report/core/common/utils.js.html +0 -226
  389. package/coverage/lcov-report/core/common/utils.offline.js.html +0 -199
  390. package/coverage/lcov-report/favicon.png +0 -0
  391. package/coverage/lcov-report/index.html +0 -476
  392. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +0 -553
  393. package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +0 -397
  394. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +0 -1294
  395. package/coverage/lcov-report/map/api/hooks/index.html +0 -161
  396. package/coverage/lcov-report/map/api/hooks/index.js.html +0 -94
  397. package/coverage/lcov-report/map/api/index.html +0 -131
  398. package/coverage/lcov-report/map/api/index.js.html +0 -139
  399. package/coverage/lcov-report/map/api/marshall.js.html +0 -178
  400. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +0 -106
  401. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +0 -169
  402. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +0 -196
  403. package/coverage/lcov-report/map/api/models/index.html +0 -176
  404. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +0 -109
  405. package/coverage/lcov-report/map/api/models/styles.model.mongodb.js.html +0 -112
  406. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +0 -274
  407. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +0 -610
  408. package/coverage/lcov-report/map/api/services/alerts/index.html +0 -131
  409. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +0 -328
  410. package/coverage/lcov-report/map/api/services/catalog/index.html +0 -116
  411. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +0 -1510
  412. package/coverage/lcov-report/map/api/services/daptiles/index.html +0 -116
  413. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +0 -310
  414. package/coverage/lcov-report/map/api/services/features/features.service.js.html +0 -544
  415. package/coverage/lcov-report/map/api/services/features/index.html +0 -131
  416. package/coverage/lcov-report/map/api/services/index.html +0 -116
  417. package/coverage/lcov-report/map/api/services/index.js.html +0 -1054
  418. package/coverage/lcov-report/map/api/services/projects/index.html +0 -116
  419. package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +0 -439
  420. package/coverage/lcov-report/map/api/services/styles/index.html +0 -116
  421. package/coverage/lcov-report/map/api/services/styles/styles.hooks.js.html +0 -196
  422. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +0 -466
  423. package/coverage/lcov-report/map/common/errors.js.html +0 -94
  424. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +0 -544
  425. package/coverage/lcov-report/map/common/grid.js.html +0 -1612
  426. package/coverage/lcov-report/map/common/index.html +0 -371
  427. package/coverage/lcov-report/map/common/index.js.html +0 -172
  428. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +0 -556
  429. package/coverage/lcov-report/map/common/moment-utils.js.html +0 -157
  430. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +0 -868
  431. package/coverage/lcov-report/map/common/opendap-utils.js.html +0 -826
  432. package/coverage/lcov-report/map/common/permissions.js.html +0 -130
  433. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +0 -418
  434. package/coverage/lcov-report/map/common/tms-utils.js.html +0 -274
  435. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +0 -364
  436. package/coverage/lcov-report/map/common/wcs-utils.js.html +0 -586
  437. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +0 -1033
  438. package/coverage/lcov-report/map/common/wfs-utils.js.html +0 -574
  439. package/coverage/lcov-report/map/common/wms-utils.js.html +0 -451
  440. package/coverage/lcov-report/map/common/wmts-utils.js.html +0 -547
  441. package/coverage/lcov-report/prettify.css +0 -1
  442. package/coverage/lcov-report/prettify.js +0 -2
  443. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  444. package/coverage/lcov-report/sorter.js +0 -196
  445. package/coverage/lcov.info +0 -11520
  446. package/coverage/map/api/hooks/hooks.catalog.js.html +0 -553
  447. package/coverage/map/api/hooks/hooks.features.js.html +0 -397
  448. package/coverage/map/api/hooks/hooks.query.js.html +0 -1294
  449. package/coverage/map/api/hooks/index.html +0 -161
  450. package/coverage/map/api/hooks/index.js.html +0 -94
  451. package/coverage/map/api/index.html +0 -131
  452. package/coverage/map/api/index.js.html +0 -139
  453. package/coverage/map/api/marshall.js.html +0 -178
  454. package/coverage/map/api/models/alerts.model.mongodb.js.html +0 -106
  455. package/coverage/map/api/models/catalog.model.mongodb.js.html +0 -169
  456. package/coverage/map/api/models/features.model.mongodb.js.html +0 -196
  457. package/coverage/map/api/models/index.html +0 -176
  458. package/coverage/map/api/models/projects.model.mongodb.js.html +0 -109
  459. package/coverage/map/api/models/styles.model.mongodb.js.html +0 -112
  460. package/coverage/map/api/services/alerts/alerts.hooks.js.html +0 -274
  461. package/coverage/map/api/services/alerts/alerts.service.js.html +0 -610
  462. package/coverage/map/api/services/alerts/index.html +0 -131
  463. package/coverage/map/api/services/catalog/catalog.hooks.js.html +0 -328
  464. package/coverage/map/api/services/catalog/index.html +0 -116
  465. package/coverage/map/api/services/daptiles/daptiles.service.js.html +0 -1510
  466. package/coverage/map/api/services/daptiles/index.html +0 -116
  467. package/coverage/map/api/services/features/features.hooks.js.html +0 -310
  468. package/coverage/map/api/services/features/features.service.js.html +0 -544
  469. package/coverage/map/api/services/features/index.html +0 -131
  470. package/coverage/map/api/services/index.html +0 -116
  471. package/coverage/map/api/services/index.js.html +0 -1054
  472. package/coverage/map/api/services/projects/index.html +0 -116
  473. package/coverage/map/api/services/projects/projects.hooks.js.html +0 -439
  474. package/coverage/map/api/services/styles/index.html +0 -116
  475. package/coverage/map/api/services/styles/styles.hooks.js.html +0 -196
  476. package/coverage/map/common/dynamic-grid-source.js.html +0 -466
  477. package/coverage/map/common/errors.js.html +0 -94
  478. package/coverage/map/common/geotiff-grid-source.js.html +0 -544
  479. package/coverage/map/common/grid.js.html +0 -1612
  480. package/coverage/map/common/index.html +0 -371
  481. package/coverage/map/common/index.js.html +0 -172
  482. package/coverage/map/common/meteo-model-grid-source.js.html +0 -556
  483. package/coverage/map/common/moment-utils.js.html +0 -157
  484. package/coverage/map/common/opendap-grid-source.js.html +0 -868
  485. package/coverage/map/common/opendap-utils.js.html +0 -826
  486. package/coverage/map/common/permissions.js.html +0 -130
  487. package/coverage/map/common/time-based-grid-source.js.html +0 -418
  488. package/coverage/map/common/tms-utils.js.html +0 -274
  489. package/coverage/map/common/wcs-grid-source.js.html +0 -364
  490. package/coverage/map/common/wcs-utils.js.html +0 -586
  491. package/coverage/map/common/weacast-grid-source.js.html +0 -1033
  492. package/coverage/map/common/wfs-utils.js.html +0 -574
  493. package/coverage/map/common/wms-utils.js.html +0 -451
  494. package/coverage/map/common/wmts-utils.js.html +0 -547
  495. package/coverage/prettify.css +0 -1
  496. package/coverage/prettify.js +0 -2
  497. package/coverage/sort-arrow-sprite.png +0 -0
  498. package/coverage/sorter.js +0 -196
  499. package/coverage/tmp/coverage-151198-1753351220086-0.json +0 -1
  500. package/coverage/tmp/coverage-151210-1753351220070-0.json +0 -1
  501. package/coverage/tmp/coverage-151221-1753351129816-0.json +0 -1
  502. package/coverage/tmp/coverage-151233-1753351129803-0.json +0 -1
  503. package/coverage/tmp/coverage-151240-1753351129770-0.json +0 -1
  504. package/coverage/tmp/coverage-151307-1753351220058-0.json +0 -1
  505. package/coverage/tmp/coverage-151319-1753351220044-0.json +0 -1
  506. package/coverage/tmp/coverage-151326-1753351220010-0.json +0 -1
  507. package/extras/tours/core/account-profile.js +0 -32
  508. package/extras/tours/core/account.js +0 -143
  509. package/extras/tours/core/add-member.js +0 -75
  510. package/extras/tours/core/add-tag.js +0 -13
  511. package/extras/tours/core/create-group.js +0 -19
  512. package/extras/tours/core/create-organisation.js +0 -19
  513. package/extras/tours/core/create-tag.js +0 -26
  514. package/extras/tours/core/edit-member-role.js +0 -13
  515. package/extras/tours/core/groups.js +0 -65
  516. package/extras/tours/core/join-group.js +0 -13
  517. package/extras/tours/core/login.js +0 -41
  518. package/extras/tours/core/members.js +0 -108
  519. package/extras/tours/core/register.js +0 -61
  520. package/extras/tours/core/send-reset-password.js +0 -14
  521. package/extras/tours/core/tags.js +0 -65
  522. package/extras/tours/map/catalog-panel.js +0 -112
  523. package/extras/tours/map/fab.js +0 -26
  524. package/extras/tours/map/navigation-bar.js +0 -187
  525. package/extras/tours/map/side-nav.js +0 -36
  526. package/test/api/core/test-log-2025-02-05.log +0 -23
  527. package/test/api/core/test-log-2025-05-21.log +0 -15
  528. package/test/api/core/test-log-2025-06-25.log +0 -9
  529. package/test/api/core/test-log-2025-07-24.log +0 -44
  530. package/test/api/map/test-log-2025-05-27.log +0 -13
  531. package/test/api/map/test-log-2025-06-23.log +0 -7
  532. package/test/api/map/test-log-2025-07-24.log +0 -11
  533. package/test/client/core/api.js +0 -361
  534. package/test/client/core/index.js +0 -9
  535. package/test/client/index.js +0 -4
  536. package/test/client/map/index.js +0 -5
  537. package/test.client.js +0 -1
  538. /package/{test/client/core/time.js → extras/tests/core/time.mjs} +0 -0
  539. /package/extras/tours/{map/add-layer.js → add-layer.js} +0 -0
  540. /package/extras/tours/{map/catalog-categories.js → catalog-categories.js} +0 -0
  541. /package/extras/tours/{map/connect-layer.js → connect-layer.js} +0 -0
  542. /package/extras/tours/{map/create-layer.js → create-layer.js} +0 -0
  543. /package/extras/tours/{map/create-view.js → create-view.js} +0 -0
  544. /package/extras/tours/{map/import-layer.js → import-layer.js} +0 -0
  545. /package/extras/tours/{map/timeline.js → pane.bottom.js} +0 -0
@@ -1,17 +1,25 @@
1
+ import config from 'config'
1
2
  import _ from 'lodash'
2
3
  import logger from 'loglevel'
3
- import config from 'config'
4
- import { Store } from '../../../core/client/index.js'
5
- import { filterContent, bindContent, listenToServiceEvents, unlistenToServiceEvents } from '../../../core/client/utils/index.js'
4
+ import sift from 'sift'
5
+ import { Store } from '../../../core/client/store.js'
6
+ import { Events } from '../../../core/client/events.js'
7
+ import { api } from '../../../core/client/api.js'
8
+ import { isDataOperation } from '../../../core/client/utils/utils.services.js'
9
+ import { bindContent, filterContent, listenToServiceEvents, unlistenToServiceEvents } from '../../../core/client/utils/index.js'
6
10
  import { Geolocation } from '../geolocation.js'
7
- import { setEngineJwt, getLayers, getCategories } from '../utils/utils.catalog.js'
11
+ import { getCategories, getLayers, getLayersByCategory, getOrphanLayers, getSublegends, processTranslations, setEngineJwt } from '../utils/utils.catalog.js'
8
12
  import * as layers from '../utils/utils.layers.js'
9
13
  import { getCatalogProjectQuery } from '../utils/utils.project.js'
10
14
 
11
15
  export const activity = {
16
+ emits: [
17
+ 'layer-filter-toggled'
18
+ ],
12
19
  data () {
13
20
  return {
14
21
  layerCategories: [],
22
+ orphanLayers: [],
15
23
  variables: [],
16
24
  engine: 'leaflet',
17
25
  engineReady: false,
@@ -84,16 +92,66 @@ export const activity = {
84
92
  if (context) categories = categories.concat(await getCategories({ context }))
85
93
  return categories
86
94
  },
95
+ async getCatalogSublegends () {
96
+ // We get sublegends coming from global catalog first if any
97
+ let sublegends = await getSublegends()
98
+ // Then we get categories coming from contextual catalog if any
99
+ const context = Store.get('context')
100
+ if (context) sublegends = sublegends.concat(await getSublegends({ context }))
101
+ return sublegends
102
+ },
87
103
  async addCatalogCategory (category) {
88
104
  this.layerCategories.push(category)
89
105
  },
106
+ // Retrieve layer categories from catalog
90
107
  async refreshLayerCategories () {
91
108
  this.layerCategories.splice(0, this.layerCategories.length)
92
109
  const layerCategories = await this.getCatalogCategories()
93
110
  for (let i = 0; i < layerCategories.length; i++) {
94
111
  this.addCatalogCategory(layerCategories[i])
95
112
  }
113
+ await this.refreshOrphanLayers()
114
+ this.reorderLayers()
115
+ },
116
+ getOrphanLayerByName (name) {
117
+ return this.orphanLayers.find(l => l?.name === name)
118
+ },
119
+ isOrphanLayer (layer) {
120
+ return this.orphanLayers.some(l => l?.name === layer.name)
121
+ },
122
+ // To be overriden by apps to perform any operation (eg serialization) when the category order has been changed by the user
123
+ // By default perform layer ordering in the underlying engine
124
+ async updateCategoriesOrder (sourceCategoryId, targetCategoryId) {
125
+ this.reorderLayers()
126
+ },
127
+ // To be overriden by apps to perform any operation (eg serialization) when the layer order has been changed by the user in a category
128
+ // By default perform layer ordering in the underlying engine
129
+ // Data payload is like { layers } in order to ease direct update of the target category
130
+ async updateLayersOrder (sourceCategoryId, data, movedLayer) {
131
+ this.reorderLayers()
132
+ },
133
+ // To be overriden by apps to perform any operations (eg serialization) when the layer order has been changed by the user in the orphan layer list
134
+ // By default perform layer ordering in the underlying engine
135
+ async updateOrphanLayersOrder (orphanLayers, movedLayer) {
136
+ this.reorderLayers()
137
+ },
138
+ // Perform layer ordering in the underlying engine according to current order in categories and layer list
139
+ reorderLayers () {
140
+ if (typeof this.bringLayerToFront !== 'function') return
141
+ for (let i = this.layerCategories.length - 1; i >= 0; i--) {
142
+ const category = this.layerCategories[i]
143
+ if (!category?.layers) continue
144
+ for (let j = category.layers.length - 1; j >= 0; j--) {
145
+ const layer = category.layers[j]
146
+ this.bringLayerToFront(layer)
147
+ }
148
+ }
149
+ for (let i = this.orphanLayers.length - 1; i >= 0; i--) {
150
+ const layer = this.orphanLayers[i]
151
+ this.bringLayerToFront(layer.name)
152
+ }
96
153
  },
154
+ // Retrieve layers from catalog
97
155
  async refreshLayers () {
98
156
  // Clear layers and variables
99
157
  this.clearLayers()
@@ -104,12 +162,19 @@ export const activity = {
104
162
  for (let i = 0; i < catalogLayers.length; i++) {
105
163
  await this.addCatalogLayer(catalogLayers[i])
106
164
  }
165
+ await this.refreshOrphanLayers()
107
166
  // We need at least an active background
108
167
  const hasVisibleBaseLayer = catalogLayers.find((layer) => (layer.type === 'BaseLayer') && layer.isVisible)
109
168
  if (!hasVisibleBaseLayer) {
110
169
  const baseLayer = catalogLayers.find((layer) => (layer.type === 'BaseLayer'))
111
170
  if (baseLayer) await this.showLayer(baseLayer.name)
112
171
  }
172
+ this.reorderLayers()
173
+ },
174
+ // Update orphan layers list (ie layers without any category) based on current loaded categories/layers
175
+ async refreshOrphanLayers () {
176
+ const layersByCategory = getLayersByCategory(this.layers, this.layerCategories)
177
+ this.orphanLayers = getOrphanLayers(this.layers, layersByCategory)
113
178
  },
114
179
  isInMemoryLayer: layers.isInMemoryLayer,
115
180
  isUserLayer: layers.isUserLayer,
@@ -127,35 +192,39 @@ export const activity = {
127
192
  setLayerCached: layers.setLayerCached,
128
193
  setLayerUncached: layers.setLayerUncached,
129
194
  isLayerEditable: layers.isLayerEditable,
195
+ isLayerFilterEditable: layers.isLayerFilterEditable,
130
196
  isLayerRemovable: layers.isLayerRemovable,
131
197
  isLayerStyleEditable: layers.isLayerStyleEditable,
132
198
  isLayerDataEditable: layers.isLayerDataEditable,
133
199
  canCreateLayer () {
134
- return this.$can('create', 'catalog')
200
+ return api.can('create', 'catalog')
135
201
  },
136
202
  canUpdateLayer (layer) {
137
- return layers.isInMemoryLayer(layer) || this.$can('update', 'catalog')
203
+ return layers.isInMemoryLayer(layer) || api.can('update', 'catalog')
138
204
  },
139
205
  canRemoveLayer (layer) {
140
- return layers.isInMemoryLayer(layer) || this.$can('remove', 'catalog')
206
+ return layers.isInMemoryLayer(layer) || api.can('remove', 'catalog')
141
207
  },
142
208
  async resetLayer (layer) {
143
- // Keep track of data as we will reset the layer
144
- let geoJson
145
- if (typeof this.toGeoJson === 'function') geoJson = await this.toGeoJson(layer.name)
146
- // Reset layer with new setup but keep track of current visibility state
147
- // as adding the layer back will restore default visibility state
209
+ // This requires to recreate the layer in the underlying engine with the new setup.
210
+ // So it's only necessary if the layer is already visible.
148
211
  const isVisible = this.isLayerVisible(layer.name)
149
- await this.removeLayer(layer.name)
150
- await this.addLayer(layer)
151
- if (isVisible) await this.showLayer(layer.name)
152
- if (geoJson && (typeof this.toGeoJson === 'function')) this.updateLayer(layer.name, geoJson)
212
+ if (isVisible) {
213
+ // Keep track of data as the reset will los it for in-memory layers
214
+ let geoJson
215
+ if (layers.isInMemoryLayer(layer) && (typeof this.toGeoJson === 'function')) geoJson = await this.toGeoJson(layer.name)
216
+ await this.hideLayer(layer.name)
217
+ await this.showLayer(layer.name)
218
+ if (geoJson) this.updateLayer(layer.name, geoJson)
219
+ // If min/max zoom configuration has changed we need to refresh this state as well
220
+ if (typeof this.updateLayerDisabled === 'function') this.updateLayerDisabled(layer)
221
+ }
153
222
  },
154
223
  configureLayerActions (layer) {
155
224
  let actions = _.get(this, 'activityOptions.layers.actions', [])
156
225
  // Apply filtering
157
226
  actions = filterContent(actions, _.get(this, 'activityOptions.layers.filter', {}))
158
-
227
+
159
228
  // As context is different for each item we need to clone the global action configuration
160
229
  // otherwise context will always reference the last processed item
161
230
  actions = bindContent(_.cloneDeep(actions), this, ['dialog'])
@@ -179,7 +248,10 @@ export const activity = {
179
248
  async onTriggerLayerFilter (layer, filter) {
180
249
  // Can only apply to realtime layers as we need to force a data refresh
181
250
  // removeMissing seems needed for 3d
182
- if (typeof this.updateLayer === 'function') await this.updateLayer(layer.name, null, { removeMissing: true})
251
+ if (typeof this.updateLayer === 'function') await this.updateLayer(layer.name, null, { removeMissing: true })
252
+
253
+ this.$emit('layer-filter-toggled', layer, filter)
254
+ this.$engineEvents.emit('layer-filter-toggled', layer, filter)
183
255
  },
184
256
  onZoomIn () {
185
257
  const center = this.getCenter()
@@ -192,6 +264,12 @@ export const activity = {
192
264
  onZoomToLayer (layer) {
193
265
  this.zoomToLayer(layer.name)
194
266
  },
267
+ onBringLayerToFront (layer) {
268
+ if (typeof this.bringLayerToFront === 'function') this.bringLayerToFront(layer.name)
269
+ },
270
+ onBringLayerToBack (layer) {
271
+ if (typeof this.bringLayerToBack === 'function') this.bringLayerToBack(layer.name)
272
+ },
195
273
  async onSaveLayer (layer) {
196
274
  // Stop any running edition
197
275
  if ((typeof this.isLayerEdited === 'function') && this.isLayerEdited(layer)) await this.stopEditLayer('accept')
@@ -205,16 +283,19 @@ export const activity = {
205
283
  createdLayer = await layers.saveLayer(layer)
206
284
  }
207
285
  // Add layer to current project ? Check if not coming from another planet first
208
- if (this.project && (this.project.getPlanetApi() === this.$api)) {
286
+ if (this.project && (this.project.getPlanetApi() === api)) {
209
287
  this.project.layers.push({ _id: createdLayer._id })
210
- await this.$api.getService('projects').patch(this.project._id, {
288
+ await api.getService('projects').patch(this.project._id, {
211
289
  layers: this.project.layers
212
290
  })
213
291
  }
214
292
  // Reset layer with new setup
215
293
  // It should be triggerred by real-time event
216
294
  // but as we might not always use sockets perform it anyway
217
- if (createdLayer) await this.resetLayer(createdLayer)
295
+ if (createdLayer) {
296
+ layer._id = createdLayer._id
297
+ await this.resetLayer(createdLayer)
298
+ }
218
299
  },
219
300
  editLayerByName (name, editOptions = {}) {
220
301
  // this one is used through postRobot to trigger edition
@@ -243,6 +324,9 @@ export const activity = {
243
324
  await this.resetLayer(layer)
244
325
  }
245
326
  },
327
+ async onRemoveCategory (category) {
328
+ // virtual method
329
+ },
246
330
  async onRemoveLayer (layer) {
247
331
  // Stop any running edition
248
332
  if ((typeof this.isLayerEdited === 'function') && this.isLayerEdited(layer)) await this.stopEditLayer('reject')
@@ -253,6 +337,16 @@ export const activity = {
253
337
  }
254
338
  // Removing the layer should automatically update all projects
255
339
  },
340
+ async onAddOrphanLayer (layer) {
341
+ if (!this.isOrphanLayer(layer)) {
342
+ await this.refreshOrphanLayers()
343
+ }
344
+ },
345
+ onRemoveOrphanLayer (layer) {
346
+ if (this.isOrphanLayer(layer)) {
347
+ _.remove(this.orphanLayers, orphanLayer => layer._id ? orphanLayer._id === layer._id : orphanLayer.name === layer.name)
348
+ }
349
+ },
256
350
  onEngineReady (engine) {
257
351
  this.engine = engine
258
352
  this.engineReady = true
@@ -263,8 +357,8 @@ export const activity = {
263
357
  },
264
358
  listenToCatalogServiceEvents () {
265
359
  // Listen about changes in global/contextual catalog services
266
- const globalCatalogService = this.$api.getService('catalog', 'global')
267
- const catalogService = this.$api.getService('catalog')
360
+ const globalCatalogService = api.getService('catalog', 'global')
361
+ const catalogService = api.getService('catalog')
268
362
  this.globalCatalogListeners = listenToServiceEvents('catalog', {
269
363
  context: 'global', all: this.onCatalogUpdated, removed: (object) => this.onCatalogUpdated(object, 'removed')
270
364
  }, this.globalCatalogListeners)
@@ -321,36 +415,79 @@ export const activity = {
321
415
  finalize () {
322
416
  this.unlistenToCatalogServiceEvents()
323
417
  },
418
+ async refreshLayer (layer, event) {
419
+ // Updating a layer requires to remove/add it again to cover all use cases (eg style edition, etc.)
420
+ // Here we preferably find layer by ID as renaming could have occured from another client
421
+ let planetApi
422
+ if (layer && (typeof layer.getPlanetApi === 'function')) {
423
+ planetApi = layer.getPlanetApi()
424
+ }
425
+ if (layer) {
426
+ // Stop any running edition
427
+ if ((typeof this.isLayerEdited === 'function') && this.isLayerEdited(layer)) await this.stopEditLayer('reject')
428
+ // Check if available for current engine
429
+ if (layer[this.engine]) {
430
+ let name = layer.name
431
+ // We might have a patch event changing the name so that in this case we need to use the old one
432
+ // because layers are indexed by name in map activities
433
+ const previousLayer = this.getLayerById(layer._id)
434
+ if (previousLayer && (previousLayer.name !== name)) name = previousLayer.name
435
+ await this.removeLayer(name)
436
+ }
437
+ }
438
+ if (event !== 'removed') {
439
+ // Do we need to inject a token or restore planet API ?
440
+ if (planetApi) Object.assign(layer, { getPlanetApi: () => planetApi })
441
+ await setEngineJwt([layer], planetApi)
442
+ processTranslations(layer)
443
+ await this.addCatalogLayer(layer)
444
+ }
445
+ },
446
+ requestRefreshLayer (layer, event) {
447
+ // As this is used by realtime events we need to avoid reentrance in any case
448
+ // multiple events regarding the same layer come in at almost the same time.
449
+ // This is for instance the case when saving a layer as a created then patched event come in.
450
+ // So we need something similar to _.debounce() but for each possible layer argument.
451
+ // Otherwise when two events are almost received at the same time but target different layers only the last one will be considered.
452
+ // Realtime events only targets layer saved in DB so that they should always have a unique ID we can rely on
453
+ const layerId = layer._id
454
+ const refreshLayer = async () => {
455
+ const requests = this.pendingLayerRefresh[layerId]
456
+ delete this.pendingLayerRefresh[layerId]
457
+ for (let i = 0; i< requests.length; i++) {
458
+ const request = requests[i]
459
+ await this.refreshLayer(request.layer, request.event)
460
+ }
461
+ }
462
+ if (!this.pendingLayerRefresh) this.pendingLayerRefresh = {}
463
+ // If a refresh has already been requested push new event to operation queue
464
+ if (this.pendingLayerRefresh[layerId]) {
465
+ // The way a layer is updated requires to remove/add it again to cover all use cases (eg style edition, etc.).
466
+ // As a consequence create/patch/update operations results in the same operations, we can avoid multiple update by "merging"
467
+ const lastRequest = _.last(this.pendingLayerRefresh[layerId])
468
+ if (isDataOperation(lastRequest.event) !== isDataOperation(event)) {
469
+ this.pendingLayerRefresh[layerId].push({ event, layer })
470
+ } else {
471
+ // The last operation "wins" otherwise
472
+ this.pendingLayerRefresh[layerId].splice(-1, 1, { event, layer })
473
+ }
474
+ } else {
475
+ this.pendingLayerRefresh[layerId] = [{ event, layer }]
476
+ setTimeout(refreshLayer, 500)
477
+ }
478
+ },
324
479
  async onCatalogUpdated (object, event) {
325
480
  switch (object.type) {
326
481
  case 'Category':
327
482
  // In any case we rebuild categories
328
- this.refreshLayerCategories()
483
+ await this.requestRefreshLayerCategories()
329
484
  break
330
485
  case 'Context':
331
486
  case 'Service':
332
487
  // Nothing to do
333
488
  break
334
489
  default: {
335
- // Updating a layer requires to remove/add it again to cover all use cases
336
- // (eg style edition, etc.)
337
- // Here we find layer by ID as renaming could have occured from another client
338
- const layer = this.getLayerById(object._id)
339
- let planetApi
340
- if (layer && (typeof layer.getPlanetApi === 'function')) {
341
- planetApi = layer.getPlanetApi()
342
- }
343
- if (layer) {
344
- // Stop any running edition
345
- if ((typeof this.isLayerEdited === 'function') && this.isLayerEdited(layer)) await this.stopEditLayer('reject')
346
- await this.removeCatalogLayer(layer)
347
- }
348
- if (event !== 'removed') {
349
- // Do we need to inject a token or restore planet API ?
350
- if (planetApi) Object.assign(object, { getPlanetApi: () => planetApi })
351
- await setEngineJwt([object], planetApi)
352
- await this.addCatalogLayer(object)
353
- }
490
+ await this.requestRefreshLayer(object, event)
354
491
  break
355
492
  }
356
493
  }
@@ -369,22 +506,31 @@ export const activity = {
369
506
  this.$engineEvents.on('map-ready', this.onEngineReady)
370
507
  this.$engineEvents.on('globe-ready', this.onEngineReady)
371
508
  this.$engineEvents.on('layer-added', this.configureLayerActions)
509
+ this.$engineEvents.on('layer-added', this.onAddOrphanLayer)
510
+ this.$engineEvents.on('layer-removed', this.onRemoveOrphanLayer)
511
+ // As we'd like to manage layer ordering we force to refresh it
512
+ // because by default Leaflet will put new elements at the end of the DOM child list.
513
+ this.$engineEvents.on('layer-shown', this.reorderLayers)
372
514
  },
373
515
  mounted () {
516
+ this.requestRefreshLayerCategories = _.debounce(this.refreshLayerCategories, 200)
374
517
  // Target online/offline service depending on status
375
- this.$events.on('navigator-disconnected', this.resetCatalogServiceEventsListeners)
376
- this.$events.on('navigator-reconnected', this.resetCatalogServiceEventsListeners)
377
- this.$events.on('websocket-disconnected', this.resetCatalogServiceEventsListeners)
378
- this.$events.on('websocket-reconnected', this.resetCatalogServiceEventsListeners)
518
+ Events.on('navigator-disconnected', this.resetCatalogServiceEventsListeners)
519
+ Events.on('navigator-reconnected', this.resetCatalogServiceEventsListeners)
520
+ Events.on('websocket-disconnected', this.resetCatalogServiceEventsListeners)
521
+ Events.on('websocket-reconnected', this.resetCatalogServiceEventsListeners)
379
522
  },
380
523
  beforeUnmount () {
381
524
  this.$engineEvents.off('map-ready', this.onEngineReady)
382
525
  this.$engineEvents.off('globe-ready', this.onEngineReady)
383
526
  this.$engineEvents.off('layer-added', this.configureLayerActions)
384
- this.$events.off('navigator-disconnected', this.resetCatalogServiceEventsListeners)
385
- this.$events.off('navigator-reconnected', this.resetCatalogServiceEventsListeners)
386
- this.$events.off('websocket-disconnected', this.resetCatalogServiceEventsListeners)
387
- this.$events.off('websocket-reconnected', this.resetCatalogServiceEventsListeners)
527
+ this.$engineEvents.off('layer-added', this.onAddOrphanLayer)
528
+ this.$engineEvents.off('layer-removed', this.onRemoveOrphanLayer)
529
+ this.$engineEvents.off('layer-shown', this.reorderLayers)
530
+ Events.off('navigator-disconnected', this.resetCatalogServiceEventsListeners)
531
+ Events.off('navigator-reconnected', this.resetCatalogServiceEventsListeners)
532
+ Events.off('websocket-disconnected', this.resetCatalogServiceEventsListeners)
533
+ Events.off('websocket-reconnected', this.resetCatalogServiceEventsListeners)
388
534
  this.finalize()
389
535
  }
390
536
  }
@@ -1,7 +1,7 @@
1
1
  import _ from 'lodash'
2
2
  import moment from 'moment'
3
3
  import sift from 'sift'
4
- import { utils as kCoreUtils, Time, Store, LocalStorage } from '../../../core/client/index.js'
4
+ import { api, utils as kCoreUtils, Time, Store, Events, LocalStorage } from '../../../core/client/index.js'
5
5
  import { isTerrainLayer } from '../utils/utils.layers.js'
6
6
 
7
7
  export const context = {
@@ -15,7 +15,7 @@ export const context = {
15
15
  if (_.has(this, `activityOptions.restore.${context}`)) {
16
16
  if (!_.get(this, `activityOptions.restore.${context}`)) return false
17
17
  }
18
- return this.$store.get(`restore.${context}`)
18
+ return Store.get(`restore.${context}`)
19
19
  },
20
20
  getRouteContext (context) {
21
21
  switch (context) {
@@ -103,7 +103,7 @@ export const context = {
103
103
  if (asQuery) Object.assign(route.query, parameters)
104
104
  else Object.assign(route.params, parameters)
105
105
  // We catch as replacing with similar params raises a duplicate navigation error
106
- this.$router.replace(route).catch(_ => {})
106
+ if (this.$router) this.$router.replace(route).catch(_ => {})
107
107
  },
108
108
  async setContextParameters (context, targetParameters) {
109
109
  switch (context) {
@@ -185,7 +185,7 @@ export const context = {
185
185
  // Check for a home context if not already retrieved
186
186
  // Use undefined here to check for a first try as if we find none we set it to null
187
187
  if (_.isUndefined(this.homeContext)) {
188
- const response = await this.$api.getService('catalog').find({ query: { type: 'Context', isDefault: true } })
188
+ const response = await api.getService('catalog').find({ query: { type: 'Context', isDefault: true } })
189
189
  this.homeContext = (response.data.length > 0 ? response.data[0] : null)
190
190
  }
191
191
  if (this.homeContext) targetParameters = this.homeContext
@@ -233,16 +233,16 @@ export const context = {
233
233
  if (hasLayers) {
234
234
  Object.assign(context, this.getContextParameters('layers'))
235
235
  }
236
- context = await this.$api.getService('catalog').create(context)
236
+ context = await api.getService('catalog').create(context)
237
237
  return context
238
238
  },
239
239
  async loadContext (context) {
240
240
  // If not context object retrieve it from catalog first
241
241
  if (typeof context === 'string') {
242
242
  if (kCoreUtils.isObjectID(context)) {
243
- context = await this.$api.getService('catalog').get(context)
243
+ context = await api.getService('catalog').get(context)
244
244
  } else {
245
- const response = await this.$api.getService('catalog').find({ query: { type: 'Context', name: context } })
245
+ const response = await api.getService('catalog').find({ query: { type: 'Context', name: context } })
246
246
  context = (response.data.length > 0 ? response.data[0] : null)
247
247
  }
248
248
  }
@@ -260,11 +260,11 @@ export const context = {
260
260
  },
261
261
  mounted () {
262
262
  // Whenever restore settings are updated, update view as well
263
- this.$events.on('restore-view-changed', this.updateViewSettings)
264
- this.$events.on('restore-layers-changed', this.updateLayersSettings)
263
+ Events.on('restore-view-changed', this.updateViewSettings)
264
+ Events.on('restore-layers-changed', this.updateLayersSettings)
265
265
  },
266
266
  beforeUnmount () {
267
- this.$events.off('restore-view-changed', this.updateViewSettings)
268
- this.$events.off('restore-layers-changed', this.updateLayersSettings)
267
+ Events.off('restore-view-changed', this.updateViewSettings)
268
+ Events.off('restore-layers-changed', this.updateLayersSettings)
269
269
  }
270
270
  }
@@ -1,6 +1,8 @@
1
1
  import _ from 'lodash'
2
2
  import sift from 'sift'
3
3
  import logger from 'loglevel'
4
+ import { Events } from '../../../core/client/events.js'
5
+ import { api } from '../../../core/client/api.js'
4
6
  import { listenToServiceEvents, unlistenToServiceEvents } from '../../../core/client/utils/index.js'
5
7
  import * as features from '../utils/utils.features.js'
6
8
  import * as layers from '../utils/utils.layers.js'
@@ -128,7 +130,7 @@ export const featureService = {
128
130
  },
129
131
  created () {
130
132
  // Extend timeout for large write operations
131
- this.$api.getService('features').timeout = 60 * 60 * 1000 // 1h should be sufficient since we also have size limits
133
+ api.getService('features').timeout = 60 * 60 * 1000 // 1h should be sufficient since we also have size limits
132
134
  },
133
135
  mounted () {
134
136
  // Here we need to listen to service events for all realtime layers
@@ -137,19 +139,19 @@ export const featureService = {
137
139
  this.$engineEvents.on('layer-added', this.listenToFeaturesServiceEventsForLayer)
138
140
  this.$engineEvents.on('layer-removed', this.unlistenToFeaturesServiceEventsForLayer)
139
141
  // Target online/offline service depending on status
140
- this.$events.on('navigator-disconnected', this.listenToFeaturesServiceEventsForLayers)
141
- this.$events.on('navigator-reconnected', this.listenToFeaturesServiceEventsForLayers)
142
- this.$events.on('websocket-disconnected', this.listenToFeaturesServiceEventsForLayers)
143
- this.$events.on('websocket-reconnected', this.listenToFeaturesServiceEventsForLayers)
142
+ Events.on('navigator-disconnected', this.listenToFeaturesServiceEventsForLayers)
143
+ Events.on('navigator-reconnected', this.listenToFeaturesServiceEventsForLayers)
144
+ Events.on('websocket-disconnected', this.listenToFeaturesServiceEventsForLayers)
145
+ Events.on('websocket-reconnected', this.listenToFeaturesServiceEventsForLayers)
144
146
  },
145
147
  beforeUnmount () {
146
148
  // Remove all listeners
147
149
  this.unlistenToFeaturesServiceEventsForLayers()
148
150
  this.$engineEvents.off('layer-added', this.listenToFeaturesServiceEventsForLayer)
149
151
  this.$engineEvents.off('layer-removed', this.unlistenToFeaturesServiceEventsForLayer)
150
- this.$events.off('navigator-disconnected', this.listenToFeaturesServiceEventsForLayers)
151
- this.$events.off('navigator-reconnected', this.listenToFeaturesServiceEventsForLayers)
152
- this.$events.off('websocket-disconnected', this.listenToFeaturesServiceEventsForLayers)
153
- this.$events.off('websocket-reconnected', this.listenToFeaturesServiceEventsForLayers)
152
+ Events.off('navigator-disconnected', this.listenToFeaturesServiceEventsForLayers)
153
+ Events.off('navigator-reconnected', this.listenToFeaturesServiceEventsForLayers)
154
+ Events.off('websocket-disconnected', this.listenToFeaturesServiceEventsForLayers)
155
+ Events.off('websocket-reconnected', this.listenToFeaturesServiceEventsForLayers)
154
156
  }
155
157
  }
@@ -1,5 +1,7 @@
1
1
  import _ from 'lodash'
2
2
  import logger from 'loglevel'
3
+ import { Events } from '../../../core/client/events.js'
4
+ import { api } from '../../../core/client/api.js'
3
5
  import { getForecastForLocation, getForecastProbe, getForecastForFeature } from '../utils/utils.weacast.js'
4
6
 
5
7
  export const weacast = {
@@ -16,7 +18,7 @@ export const weacast = {
16
18
  methods: {
17
19
  getWeacastApi () {
18
20
  // As we usually proxy weacast service we use our API unless another client has been specified by override
19
- return this.$api
21
+ return api
20
22
  },
21
23
  async setupWeacast () {
22
24
  try {
@@ -119,11 +121,11 @@ export const weacast = {
119
121
  }
120
122
  },
121
123
  created () {
122
- this.$events.on('time-current-time-changed', this.onCurrentForecastTimeChanged)
124
+ Events.on('time-current-time-changed', this.onCurrentForecastTimeChanged)
123
125
  this.$engineEvents.on('selected-level-changed', this.onWeacastSelectedLevelChanged)
124
126
  },
125
127
  beforeUnmount () {
126
- this.$events.off('time-current-time-changed', this.onCurrentForecastTimeChanged)
128
+ Events.off('time-current-time-changed', this.onCurrentForecastTimeChanged)
127
129
  this.$engineEvents.off('selected-level-changed', this.onWeacastSelectedLevelChanged)
128
130
  }
129
131
  }
@@ -1,6 +1,6 @@
1
1
  import logger from 'loglevel'
2
2
  import _ from 'lodash'
3
- import geojsonhint from '@mapbox/geojsonhint'
3
+ //import geojsonhint from '@mapbox/geojsonhint'
4
4
  import { i18n } from '../../../core/client/i18n.js'
5
5
 
6
6
  export const GEOJSONReader = {
@@ -38,6 +38,7 @@ export const GEOJSONReader = {
38
38
  }
39
39
  }
40
40
  // lint the geosjon file
41
+ /*
41
42
  const messages = geojsonhint.hint(content, options)
42
43
  // filter the message according the level to find the errors
43
44
  const errors = _.filter(messages, message => {
@@ -48,6 +49,7 @@ export const GEOJSONReader = {
48
49
  reject(new Error(i18n.t('errors.INVALID_GEOJSON_FILE', { file: file.name }), { errors }))
49
50
  return
50
51
  }
52
+ */
51
53
  // the geosjon file is correct
52
54
  resolve(content)
53
55
  }
@@ -4,7 +4,7 @@ import config from 'config'
4
4
  import moment from 'moment'
5
5
  import { i18n, Events, Store, api, Layout } from '../../../core/client/index.js'
6
6
  import * as composables from '../../../core/client/composables/index.js'
7
- import { base64Encode, getAppLocale } from '../../../core/client/utils/index.js'
7
+ import { base64Encode, getLocale } from '../../../core/client/utils/index.js'
8
8
  import { exportFile, Notify } from 'quasar'
9
9
  import { image } from '@pdfme/schemas'
10
10
  import { generate } from '@pdfme/generator'
@@ -54,7 +54,7 @@ export async function capture (values) {
54
54
  layout: getLayout(values),
55
55
  time: dateArray[index],
56
56
  basePath: _.has(values, 'basePath') ? values.basePath : '/#/home/',
57
- lang: getAppLocale()
57
+ lang: getLocale()
58
58
  })
59
59
  const response = await fetch(endpoint, options)
60
60
  if (response.ok) {
@@ -105,7 +105,7 @@ function headerFooterComponent (text, position) {
105
105
  return { content: [{ component: _.get(config, `capture.${position}.component`, 'KCaptureTextArea'), text, position }], visible: true }
106
106
  }
107
107
  function northComponent (position) {
108
- const northSticky = Layout.findSticky('north-sticky')
108
+ const northSticky = Layout.findSticky('north-arrow-sticky')
109
109
  return { content: [{ ...northSticky, position, offset: [0, 5], visible: true }] }
110
110
  }
111
111
  function legendComponent () {
@@ -1,7 +1,7 @@
1
1
  import _ from 'lodash'
2
2
  import sift from 'sift'
3
+ import { api, i18n, Store } from '../../../core/client/index.js'
3
4
  import { buildUrl } from '../../../core/common/index.js'
4
- import { i18n, api, Store } from '../../../core/client/index.js'
5
5
 
6
6
  // Helper to set a JWT as query param in a target URL
7
7
  export function setUrlJwt (item, path, baseUrl, jwtField, jwt) {
@@ -61,7 +61,7 @@ export async function setEngineJwt (layers, planetApi) {
61
61
  }
62
62
 
63
63
  export function getLayersByCategory (layers, categories) {
64
- const categorizedLayers = _.clone(layers)
64
+ const categorizedLayers = _.clone(Array.isArray(layers) ? layers : _.values(layers))
65
65
  const layersByCategory = {}
66
66
  _.forEach(categories, category => {
67
67
  // Built-in categories use filtering while user-defined ones use layers list
@@ -77,18 +77,22 @@ export function getLayersByCategory (layers, categories) {
77
77
  layersByCategory[category.name] = _.orderBy(layersByCategory[category.name],
78
78
  [(layer) => _.get(layer, _.get(category, 'options.orderBy', '_id'))],
79
79
  [_.get(category, 'options.order', 'asc')])
80
+
81
+ if (layers.length > 0 && category?.layers) {
82
+ layersByCategory[category.name] = category.layers.map(layerName => layers.find(l => l.name === layerName))
83
+ }
80
84
  })
81
85
  return layersByCategory
82
86
  }
83
87
 
84
88
  export function getOrphanLayers (layers, layersByCategory) {
85
- const categories = _.flatten(_.values(layersByCategory))
86
- const orphanLayers = _.difference(layers, categories)
89
+ const layersFromCategories = _.flatten(_.values(layersByCategory))
90
+ const orphanLayers = _.difference(Array.isArray(layers) ? layers : _.values(layers), layersFromCategories)
87
91
  // Order by
88
92
  return _.orderBy(orphanLayers, [(layer) => _.get(layer, '_id')], ['asc'])
89
93
  }
90
94
 
91
- function processTranslations (item) {
95
+ export function processTranslations (item) {
92
96
  if (item.i18n) i18n.registerTranslation(item.i18n)
93
97
  if (!_.has(item, 'label')) item.label = i18n.tie(item.name)
94
98
  if (_.has(item, 'description')) item.description = i18n.tie(item.description)