@kalisio/kdk 2.6.3 → 2.7.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 (419) hide show
  1. package/core/api/application.js +2 -4
  2. package/core/api/authentication.js +2 -3
  3. package/core/api/db.js +10 -2
  4. package/core/api/hooks/hooks.authorisations.js +4 -2
  5. package/core/api/hooks/hooks.push.js +6 -2
  6. package/core/api/hooks/hooks.query.js +29 -12
  7. package/core/api/hooks/hooks.users.js +30 -17
  8. package/core/api/models/configurations.model.mongodb.js +4 -0
  9. package/core/api/services/authorisations/authorisations.service.js +1 -1
  10. package/core/api/services/configurations/configurations.hooks.js +33 -0
  11. package/core/api/services/index.js +41 -7
  12. package/core/api/services/messages/messages.hooks.js +9 -3
  13. package/core/client/api.js +14 -1
  14. package/core/client/capabilities.js +1 -6
  15. package/core/client/components/KAvatar.vue +24 -20
  16. package/core/client/components/account/KProfile.vue +10 -71
  17. package/core/client/components/account/index.js +0 -2
  18. package/core/client/components/app/KSettings.vue +1 -0
  19. package/core/client/components/collection/KBoard.vue +4 -3
  20. package/core/client/components/collection/KCardSection.vue +1 -0
  21. package/core/client/components/collection/KGrid.vue +2 -0
  22. package/core/client/components/collection/KTable.vue +5 -1
  23. package/core/client/components/collection/KTimeLine.vue +9 -1
  24. package/core/client/components/collection/index.js +0 -2
  25. package/core/client/components/form/KChipsField.vue +2 -1
  26. package/core/client/components/form/KEmailField.vue +1 -0
  27. package/core/client/components/form/KFileField.vue +22 -1
  28. package/core/client/components/form/KForm.vue +2 -0
  29. package/core/client/components/form/KItemField.vue +1 -0
  30. package/core/client/components/form/KNumberField.vue +1 -0
  31. package/core/client/components/form/KPasswordField.vue +1 -0
  32. package/core/client/components/form/KPhoneField.vue +1 -0
  33. package/core/client/components/form/KPropertyItemField.vue +1 -0
  34. package/core/client/components/form/KResolutionField.vue +1 -0
  35. package/core/client/components/form/KSelectField.vue +31 -0
  36. package/core/client/components/form/KTagField.vue +1 -0
  37. package/core/client/components/form/KTextField.vue +1 -0
  38. package/core/client/components/form/KTokenField.vue +1 -0
  39. package/core/client/components/form/KUnitField.vue +1 -0
  40. package/core/client/components/form/KUrlField.vue +1 -0
  41. package/core/client/components/graphics/KIcon.vue +3 -4
  42. package/core/client/components/layout/KPage.vue +1 -0
  43. package/core/client/components/layout/KWindow.vue +6 -3
  44. package/core/client/components/messages/KMessageComposer.vue +2 -1
  45. package/core/client/components/messages/KMessagesTimeLine.vue +1 -1
  46. package/core/client/components/time/KDate.vue +1 -2
  47. package/core/client/components/time/KDateTime.vue +11 -11
  48. package/core/client/components/time/KTime.vue +1 -1
  49. package/core/client/composables/collection.js +33 -8
  50. package/core/client/composables/errors.js +1 -1
  51. package/core/client/composables/layout.js +9 -9
  52. package/core/client/configurations.js +50 -0
  53. package/core/client/exporter.js +1 -1
  54. package/core/client/i18n/core_en.json +6 -39
  55. package/core/client/i18n/core_fr.json +6 -39
  56. package/core/client/index.js +2 -0
  57. package/core/client/layout.js +8 -8
  58. package/core/client/mixins/mixin.base-activity.js +5 -2
  59. package/core/client/mixins/mixin.base-field.js +3 -3
  60. package/core/client/search.js +2 -1
  61. package/core/client/utils/utils.collection.js +8 -8
  62. package/core/client/utils/utils.items.js +4 -0
  63. package/core/client/utils/utils.push.js +3 -3
  64. package/core/client/utils/utils.session.js +7 -5
  65. package/core/client/utils/utils.shapes.js +38 -7
  66. package/core/client/utils/utils.time.js +21 -22
  67. package/core/common/schemas/users.update-profile.json +3 -2
  68. package/coverage/core/api/application.js.html +1 -1
  69. package/coverage/core/api/authentication.js.html +1 -1
  70. package/coverage/core/api/db.js.html +1 -1
  71. package/coverage/core/api/hooks/hooks.authentication.js.html +1 -1
  72. package/coverage/core/api/hooks/hooks.authorisations.js.html +1 -1
  73. package/coverage/core/api/hooks/hooks.logger.js.html +1 -1
  74. package/coverage/core/api/hooks/hooks.model.js.html +1 -1
  75. package/coverage/core/api/hooks/hooks.push.js.html +22 -10
  76. package/coverage/core/api/hooks/hooks.query.js.html +33 -6
  77. package/coverage/core/api/hooks/hooks.schemas.js.html +1 -1
  78. package/coverage/core/api/hooks/hooks.service.js.html +1 -1
  79. package/coverage/core/api/hooks/hooks.storage.js.html +1 -1
  80. package/coverage/core/api/hooks/hooks.tags.js.html +1 -1
  81. package/coverage/core/api/hooks/hooks.users.js.html +4 -4
  82. package/coverage/core/api/hooks/index.html +23 -23
  83. package/coverage/core/api/hooks/index.js.html +1 -1
  84. package/coverage/core/api/index.html +1 -1
  85. package/coverage/core/api/index.js.html +1 -1
  86. package/coverage/core/api/marshall.js.html +1 -1
  87. package/coverage/core/api/models/configurations.model.mongodb.js.html +1 -1
  88. package/coverage/core/api/models/index.html +1 -1
  89. package/coverage/core/api/models/messages.model.mongodb.js.html +1 -1
  90. package/coverage/core/api/models/tags.model.mongodb.js.html +1 -1
  91. package/coverage/core/api/models/users.model.mongodb.js.html +1 -1
  92. package/coverage/core/api/services/account/account.hooks.js.html +1 -1
  93. package/coverage/core/api/services/account/account.service.js.html +1 -1
  94. package/coverage/core/api/services/account/index.html +1 -1
  95. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
  96. package/coverage/core/api/services/authorisations/authorisations.service.js.html +1 -1
  97. package/coverage/core/api/services/authorisations/index.html +1 -1
  98. package/coverage/core/api/services/configurations/configurations.hooks.js.html +1 -1
  99. package/coverage/core/api/services/configurations/index.html +1 -1
  100. package/coverage/core/api/services/databases/databases.hooks.js.html +1 -1
  101. package/coverage/core/api/services/databases/databases.service.js.html +1 -1
  102. package/coverage/core/api/services/databases/index.html +1 -1
  103. package/coverage/core/api/services/import-export/import-export.hooks.js.html +1 -1
  104. package/coverage/core/api/services/import-export/import-export.service.js.html +1 -1
  105. package/coverage/core/api/services/import-export/index.html +1 -1
  106. package/coverage/core/api/services/index.html +1 -1
  107. package/coverage/core/api/services/index.js.html +1 -1
  108. package/coverage/core/api/services/mailer/index.html +1 -1
  109. package/coverage/core/api/services/mailer/mailer.hooks.js.html +1 -1
  110. package/coverage/core/api/services/mailer/mailer.service.js.html +1 -1
  111. package/coverage/core/api/services/messages/index.html +1 -1
  112. package/coverage/core/api/services/messages/messages.hooks.js.html +1 -1
  113. package/coverage/core/api/services/push/index.html +1 -1
  114. package/coverage/core/api/services/push/push.hooks.js.html +1 -1
  115. package/coverage/core/api/services/push/push.service.js.html +1 -1
  116. package/coverage/core/api/services/storage/index.html +1 -1
  117. package/coverage/core/api/services/storage/storage.hooks.js.html +1 -1
  118. package/coverage/core/api/services/storage/storage.service.js.html +1 -1
  119. package/coverage/core/api/services/tags/index.html +1 -1
  120. package/coverage/core/api/services/tags/tags.hooks.js.html +1 -1
  121. package/coverage/core/api/services/users/index.html +1 -1
  122. package/coverage/core/api/services/users/users.hooks.js.html +1 -1
  123. package/coverage/core/api/services/users/users.service.js.html +1 -1
  124. package/coverage/core/common/errors.js.html +1 -1
  125. package/coverage/core/common/index.html +1 -1
  126. package/coverage/core/common/index.js.html +1 -1
  127. package/coverage/core/common/permissions.js.html +1 -1
  128. package/coverage/core/common/schema.js.html +1 -1
  129. package/coverage/core/common/utils.js.html +1 -1
  130. package/coverage/core/common/utils.offline.js.html +1 -1
  131. package/coverage/index.html +17 -17
  132. package/coverage/lcov-report/core/api/application.js.html +1 -1
  133. package/coverage/lcov-report/core/api/authentication.js.html +1 -1
  134. package/coverage/lcov-report/core/api/db.js.html +1 -1
  135. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +1 -1
  136. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +1 -1
  137. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +1 -1
  138. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +1 -1
  139. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +22 -10
  140. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +33 -6
  141. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +1 -1
  142. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +1 -1
  143. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +1 -1
  144. package/coverage/lcov-report/core/api/hooks/hooks.tags.js.html +1 -1
  145. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +4 -4
  146. package/coverage/lcov-report/core/api/hooks/index.html +23 -23
  147. package/coverage/lcov-report/core/api/hooks/index.js.html +1 -1
  148. package/coverage/lcov-report/core/api/index.html +1 -1
  149. package/coverage/lcov-report/core/api/index.js.html +1 -1
  150. package/coverage/lcov-report/core/api/marshall.js.html +1 -1
  151. package/coverage/lcov-report/core/api/models/configurations.model.mongodb.js.html +1 -1
  152. package/coverage/lcov-report/core/api/models/index.html +1 -1
  153. package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +1 -1
  154. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +1 -1
  155. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +1 -1
  156. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +1 -1
  157. package/coverage/lcov-report/core/api/services/account/account.service.js.html +1 -1
  158. package/coverage/lcov-report/core/api/services/account/index.html +1 -1
  159. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
  160. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +1 -1
  161. package/coverage/lcov-report/core/api/services/authorisations/index.html +1 -1
  162. package/coverage/lcov-report/core/api/services/configurations/configurations.hooks.js.html +1 -1
  163. package/coverage/lcov-report/core/api/services/configurations/index.html +1 -1
  164. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +1 -1
  165. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +1 -1
  166. package/coverage/lcov-report/core/api/services/databases/index.html +1 -1
  167. package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +1 -1
  168. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +1 -1
  169. package/coverage/lcov-report/core/api/services/import-export/index.html +1 -1
  170. package/coverage/lcov-report/core/api/services/index.html +1 -1
  171. package/coverage/lcov-report/core/api/services/index.js.html +1 -1
  172. package/coverage/lcov-report/core/api/services/mailer/index.html +1 -1
  173. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +1 -1
  174. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +1 -1
  175. package/coverage/lcov-report/core/api/services/messages/index.html +1 -1
  176. package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +1 -1
  177. package/coverage/lcov-report/core/api/services/push/index.html +1 -1
  178. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +1 -1
  179. package/coverage/lcov-report/core/api/services/push/push.service.js.html +1 -1
  180. package/coverage/lcov-report/core/api/services/storage/index.html +1 -1
  181. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +1 -1
  182. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +1 -1
  183. package/coverage/lcov-report/core/api/services/tags/index.html +1 -1
  184. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +1 -1
  185. package/coverage/lcov-report/core/api/services/users/index.html +1 -1
  186. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +1 -1
  187. package/coverage/lcov-report/core/api/services/users/users.service.js.html +1 -1
  188. package/coverage/lcov-report/core/common/errors.js.html +1 -1
  189. package/coverage/lcov-report/core/common/index.html +1 -1
  190. package/coverage/lcov-report/core/common/index.js.html +1 -1
  191. package/coverage/lcov-report/core/common/permissions.js.html +1 -1
  192. package/coverage/lcov-report/core/common/schema.js.html +1 -1
  193. package/coverage/lcov-report/core/common/utils.js.html +1 -1
  194. package/coverage/lcov-report/core/common/utils.offline.js.html +1 -1
  195. package/coverage/lcov-report/index.html +17 -17
  196. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +1 -1
  197. package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +1 -1
  198. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +184 -4
  199. package/coverage/lcov-report/map/api/hooks/index.html +5 -5
  200. package/coverage/lcov-report/map/api/hooks/index.js.html +1 -1
  201. package/coverage/lcov-report/map/api/index.html +1 -1
  202. package/coverage/lcov-report/map/api/index.js.html +1 -1
  203. package/coverage/lcov-report/map/api/marshall.js.html +1 -1
  204. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +1 -1
  205. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +1 -1
  206. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +1 -1
  207. package/coverage/lcov-report/map/api/models/index.html +1 -1
  208. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +1 -1
  209. package/coverage/lcov-report/map/api/models/styles.model.mongodb.js.html +1 -1
  210. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +1 -1
  211. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +1 -1
  212. package/coverage/lcov-report/map/api/services/alerts/index.html +1 -1
  213. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +1 -1
  214. package/coverage/lcov-report/map/api/services/catalog/index.html +1 -1
  215. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1 -1
  216. package/coverage/lcov-report/map/api/services/daptiles/index.html +1 -1
  217. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +1 -1
  218. package/coverage/lcov-report/map/api/services/features/features.service.js.html +1 -1
  219. package/coverage/lcov-report/map/api/services/features/index.html +1 -1
  220. package/coverage/lcov-report/map/api/services/index.html +1 -1
  221. package/coverage/lcov-report/map/api/services/index.js.html +1 -1
  222. package/coverage/lcov-report/map/api/services/projects/index.html +1 -1
  223. package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +1 -1
  224. package/coverage/lcov-report/map/api/services/styles/index.html +1 -1
  225. package/coverage/lcov-report/map/api/services/styles/styles.hooks.js.html +1 -1
  226. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +1 -1
  227. package/coverage/lcov-report/map/common/errors.js.html +1 -1
  228. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +1 -1
  229. package/coverage/lcov-report/map/common/grid.js.html +1 -1
  230. package/coverage/lcov-report/map/common/index.html +1 -1
  231. package/coverage/lcov-report/map/common/index.js.html +1 -1
  232. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +1 -1
  233. package/coverage/lcov-report/map/common/moment-utils.js.html +1 -1
  234. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +1 -1
  235. package/coverage/lcov-report/map/common/opendap-utils.js.html +1 -1
  236. package/coverage/lcov-report/map/common/permissions.js.html +1 -1
  237. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +1 -1
  238. package/coverage/lcov-report/map/common/tms-utils.js.html +1 -1
  239. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +1 -1
  240. package/coverage/lcov-report/map/common/wcs-utils.js.html +1 -1
  241. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +1 -1
  242. package/coverage/lcov-report/map/common/wfs-utils.js.html +1 -1
  243. package/coverage/lcov-report/map/common/wms-utils.js.html +1 -1
  244. package/coverage/lcov-report/map/common/wmts-utils.js.html +1 -1
  245. package/coverage/lcov.info +358 -280
  246. package/coverage/map/api/hooks/hooks.catalog.js.html +1 -1
  247. package/coverage/map/api/hooks/hooks.features.js.html +1 -1
  248. package/coverage/map/api/hooks/hooks.query.js.html +184 -4
  249. package/coverage/map/api/hooks/index.html +5 -5
  250. package/coverage/map/api/hooks/index.js.html +1 -1
  251. package/coverage/map/api/index.html +1 -1
  252. package/coverage/map/api/index.js.html +1 -1
  253. package/coverage/map/api/marshall.js.html +1 -1
  254. package/coverage/map/api/models/alerts.model.mongodb.js.html +1 -1
  255. package/coverage/map/api/models/catalog.model.mongodb.js.html +1 -1
  256. package/coverage/map/api/models/features.model.mongodb.js.html +1 -1
  257. package/coverage/map/api/models/index.html +1 -1
  258. package/coverage/map/api/models/projects.model.mongodb.js.html +1 -1
  259. package/coverage/map/api/models/styles.model.mongodb.js.html +1 -1
  260. package/coverage/map/api/services/alerts/alerts.hooks.js.html +1 -1
  261. package/coverage/map/api/services/alerts/alerts.service.js.html +1 -1
  262. package/coverage/map/api/services/alerts/index.html +1 -1
  263. package/coverage/map/api/services/catalog/catalog.hooks.js.html +1 -1
  264. package/coverage/map/api/services/catalog/index.html +1 -1
  265. package/coverage/map/api/services/daptiles/daptiles.service.js.html +1 -1
  266. package/coverage/map/api/services/daptiles/index.html +1 -1
  267. package/coverage/map/api/services/features/features.hooks.js.html +1 -1
  268. package/coverage/map/api/services/features/features.service.js.html +1 -1
  269. package/coverage/map/api/services/features/index.html +1 -1
  270. package/coverage/map/api/services/index.html +1 -1
  271. package/coverage/map/api/services/index.js.html +1 -1
  272. package/coverage/map/api/services/projects/index.html +1 -1
  273. package/coverage/map/api/services/projects/projects.hooks.js.html +1 -1
  274. package/coverage/map/api/services/styles/index.html +1 -1
  275. package/coverage/map/api/services/styles/styles.hooks.js.html +1 -1
  276. package/coverage/map/common/dynamic-grid-source.js.html +1 -1
  277. package/coverage/map/common/errors.js.html +1 -1
  278. package/coverage/map/common/geotiff-grid-source.js.html +1 -1
  279. package/coverage/map/common/grid.js.html +1 -1
  280. package/coverage/map/common/index.html +1 -1
  281. package/coverage/map/common/index.js.html +1 -1
  282. package/coverage/map/common/meteo-model-grid-source.js.html +1 -1
  283. package/coverage/map/common/moment-utils.js.html +1 -1
  284. package/coverage/map/common/opendap-grid-source.js.html +1 -1
  285. package/coverage/map/common/opendap-utils.js.html +1 -1
  286. package/coverage/map/common/permissions.js.html +1 -1
  287. package/coverage/map/common/time-based-grid-source.js.html +1 -1
  288. package/coverage/map/common/tms-utils.js.html +1 -1
  289. package/coverage/map/common/wcs-grid-source.js.html +1 -1
  290. package/coverage/map/common/wcs-utils.js.html +1 -1
  291. package/coverage/map/common/weacast-grid-source.js.html +1 -1
  292. package/coverage/map/common/wfs-utils.js.html +1 -1
  293. package/coverage/map/common/wms-utils.js.html +1 -1
  294. package/coverage/map/common/wmts-utils.js.html +1 -1
  295. package/coverage/tmp/coverage-1028514-1773134124472-0.json +1 -0
  296. package/coverage/tmp/coverage-1028526-1773134124448-0.json +1 -0
  297. package/coverage/tmp/coverage-1028537-1773134124431-0.json +1 -0
  298. package/coverage/tmp/coverage-1028549-1773134124401-0.json +1 -0
  299. package/coverage/tmp/{coverage-222566-1765963609278-0.json → coverage-1028556-1773134124353-0.json} +1 -1
  300. package/extras/configs/widgets.top.js +3 -3
  301. package/extras/tests/core/collection.mjs +2 -9
  302. package/map/api/hooks/hooks.catalog.js +18 -4
  303. package/map/api/services/catalog/catalog.hooks.js +3 -0
  304. package/map/api/services/features/features.hooks.js +3 -1
  305. package/map/api/services/index.js +2 -6
  306. package/map/api/services/styles/styles.hooks.js +6 -1
  307. package/map/client/components/KFeatureActionButton.vue +9 -3
  308. package/map/client/components/KFeaturesFilterManager.vue +5 -5
  309. package/map/client/components/KFilterCondition.vue +17 -10
  310. package/map/client/components/KLayerEditor.vue +49 -39
  311. package/map/client/components/KMeasureTool.vue +7 -1
  312. package/map/client/components/KTimezoneMap.vue +29 -9
  313. package/map/client/components/catalog/KLayersPanel.vue +26 -16
  314. package/map/client/components/catalog/KLayersSelector.vue +13 -2
  315. package/map/client/components/catalog/KViewsPanel.vue +5 -4
  316. package/map/client/components/form/KSelectLayersField.vue +28 -17
  317. package/map/client/components/form/KSelectViewsField.vue +18 -9
  318. package/map/client/components/form/KTimezoneField.vue +1 -2
  319. package/map/client/components/legend/KVariablesLegend.vue +10 -1
  320. package/map/client/components/location/KLocationCardSection.vue +7 -2
  321. package/map/client/components/location/KLocationMap.vue +31 -7
  322. package/map/client/components/selection/KSelectedLayerFeatures.vue +2 -2
  323. package/map/client/components/stickies/KZoomControl.vue +1 -1
  324. package/map/client/components/styles/KStyleManager.vue +4 -1
  325. package/map/client/components/widget/KTimeSeries.vue +174 -497
  326. package/map/client/components/widget/KTimeSeriesSelector.vue +72 -0
  327. package/map/client/components/widget/KTimeSeriesToolbar.vue +83 -0
  328. package/map/client/composables/catalog.js +6 -10
  329. package/map/client/composables/highlight.js +12 -9
  330. package/map/client/composables/project.js +1 -1
  331. package/map/client/composables/selection.js +8 -7
  332. package/map/client/composables/weather.js +9 -2
  333. package/map/client/geolocation.js +8 -5
  334. package/map/client/i18n/map_en.json +10 -8
  335. package/map/client/i18n/map_fr.json +9 -7
  336. package/map/client/leaflet/TiledFeatureLayer.js +85 -82
  337. package/map/client/leaflet/utils/utils.geojson.js +3 -3
  338. package/map/client/mixins/globe/mixin.base-globe.js +15 -6
  339. package/map/client/mixins/globe/mixin.geojson-layers.js +27 -18
  340. package/map/client/mixins/map/mixin.edit-layers.js +9 -1
  341. package/map/client/mixins/map/mixin.pmtiles-layers.js +118 -29
  342. package/map/client/mixins/map/mixin.tiled-mesh-layers.js +12 -5
  343. package/map/client/mixins/map/mixin.tiled-wind-layers.js +19 -10
  344. package/map/client/mixins/mixin.activity.js +23 -30
  345. package/map/client/mixins/mixin.feature-selection.js +41 -5
  346. package/map/client/planets.js +1 -1
  347. package/map/client/readers/reader.kml.js +2 -3
  348. package/map/client/utils/utils.catalog.js +36 -10
  349. package/map/client/utils/utils.layers.js +39 -8
  350. package/map/client/utils/utils.project.js +4 -0
  351. package/map/client/utils/utils.style.js +37 -7
  352. package/map/client/utils/utils.time-series.js +215 -6
  353. package/map/common/schemas/catalog.update.json +1 -1
  354. package/map/common/weacast-grid-source.js +1 -1
  355. package/package.json +3 -3
  356. package/scripts/kash/CHANGELOG.md +0 -4
  357. package/scripts/kash/README.md +0 -9
  358. package/scripts/kash/kash.sh +45 -40
  359. package/scripts/kash/scripts/run_tests.sh +1 -4
  360. package/test/api/core/authentication.test.js +9 -4
  361. package/test/api/core/config/default.cjs +1 -0
  362. package/test/api/core/hooks.test.js +6 -0
  363. package/test/api/core/index.test.js +43 -18
  364. package/test/api/core/push.test.js +8 -8
  365. package/test/api/core/test-log-2026-03-10.log +60 -0
  366. package/test/api/core/users.test.js +384 -0
  367. package/test/api/map/grid-sources.test.js +1 -1
  368. package/test/api/map/test-log-2026-03-10.log +56 -0
  369. package/vite/package.json +11 -2
  370. package/vite/test/core/composables.test.js +77 -0
  371. package/vite/vitest.config.js +13 -0
  372. package/vite/yarn.lock +1096 -18
  373. package/client/css/core.variables.scss +0 -72
  374. package/client/i18n/core_en.json +0 -744
  375. package/client/i18n/core_fr.json +0 -744
  376. package/client/i18n/map_en.json +0 -800
  377. package/client/i18n/map_fr.json +0 -800
  378. package/client/kdk.client.css +0 -47
  379. package/client/kdk.client.js +0 -41097
  380. package/client/kdk.client.map.css +0 -47
  381. package/client/kdk.client.map.js +0 -38182
  382. package/client/kdk.client.map.min.css +0 -1
  383. package/client/kdk.client.map.min.js +0 -27032
  384. package/client/kdk.client.min.css +0 -1
  385. package/client/kdk.client.min.js +0 -29074
  386. package/client/schemas/capture.create.json +0 -132
  387. package/client/schemas/catalog.update.json +0 -44
  388. package/client/schemas/messages.update.json +0 -16
  389. package/client/schemas/projects.create.json +0 -52
  390. package/client/schemas/projects.update.json +0 -52
  391. package/client/schemas/settings.update.json +0 -286
  392. package/client/schemas/tags.update.json +0 -35
  393. package/client/schemas/users.update-profile.json +0 -34
  394. package/core/client/components/account/KAccount.vue +0 -68
  395. package/core/client/components/account/KDeleteAccountManager.vue +0 -62
  396. package/core/client/components/account/KEmailManager.vue +0 -128
  397. package/core/client/components/account/KPasswordManager.vue +0 -90
  398. package/core/client/components/account/KVerifyEmailManager.vue +0 -105
  399. package/core/client/components/collection/KColumn.vue +0 -227
  400. package/core/client/components/collection/KHistory.vue +0 -113
  401. package/core/client/components/collection/KHistoryEntry.vue +0 -109
  402. package/coverage/tmp/coverage-222524-1765963609350-0.json +0 -1
  403. package/coverage/tmp/coverage-222536-1765963609335-0.json +0 -1
  404. package/coverage/tmp/coverage-222547-1765963609324-0.json +0 -1
  405. package/coverage/tmp/coverage-222559-1765963609309-0.json +0 -1
  406. package/scripts/kash/LICENSE +0 -21
  407. package/test/api/core/test-log-2025-07-31.log +0 -15
  408. package/test/api/core/test-log-2025-10-03.log +0 -18
  409. package/test/api/core/test-log-2025-11-10.log +0 -0
  410. package/test/api/core/test-log-2025-11-12.log +0 -117
  411. package/test/api/core/test-log-2025-11-27.log +0 -0
  412. package/test/api/core/test-log-2025-11-28.log +0 -17
  413. package/test/api/core/test-log-2025-12-09.log +0 -148
  414. package/test/api/core/test-log-2025-12-17.log +0 -58
  415. package/test/api/core/test-log-2026-01-29.log +0 -17
  416. package/test/api/map/test-log-2025-07-23.log +0 -1
  417. package/test/api/map/test-log-2025-11-28.log +0 -33
  418. package/test/api/map/test-log-2025-12-10.log +0 -2
  419. package/test/api/map/test-log-2026-01-06.log +0 -26
@@ -112,13 +112,13 @@ L.GeoJSON.geometryToLayer = function (geojson, options) {
112
112
  if (geometry && properties && properties.geodesic) {
113
113
  if (geometry.type === 'LineString') {
114
114
  return new L.Geodesic([L.GeoJSON.coordsToLatLngs(geometry.coordinates, 0)],
115
- Object.assign({ steps: 4 }, options.style(geojson)))
115
+ Object.assign({ steps: properties.steps || 4, wrap: properties.wrap }, options.style(geojson)))
116
116
  } else if (geometry.type === 'MultiLineString') {
117
117
  const coords = geometry.coordinates.map((lineString) => L.GeoJSON.coordsToLatLngs(lineString, 0))
118
- return new L.Geodesic(coords, Object.assign({ steps: 4 }, options.style(geojson)))
118
+ return new L.Geodesic(coords, Object.assign({ steps: properties.steps || 4, wrap: properties.wrap }, options.style(geojson)))
119
119
  } else if (geometry.type === 'Point') {
120
120
  const layer = new L.GeodesicCircle(L.GeoJSON.coordsToLatLng(geometry.coordinates),
121
- Object.assign({ fill: true, steps: 360, radius: properties.radius }, options.style(geojson)))
121
+ Object.assign({ fill: true, steps: properties.steps || 360, wrap: properties.wrap, radius: properties.radius }, options.style(geojson)))
122
122
  return layer
123
123
  }
124
124
  }
@@ -318,7 +318,7 @@ export const baseGlobe = {
318
318
  this.$emit('layer-added', layer)
319
319
  this.$engineEvents.emit('layer-added', layer)
320
320
  },
321
- async addGeoJsonLayer (layerSpec, geoJson, zoom) {
321
+ async addGeoJsonLayer (layerSpec, geoJson, zoom = true) {
322
322
  if (!generateLayerDefinition(layerSpec, geoJson)) return
323
323
  // Create an empty layer
324
324
  await this.addLayer(layerSpec)
@@ -379,12 +379,11 @@ export const baseGlobe = {
379
379
  },
380
380
  zoomIn () {
381
381
  const center = this.getCenter()
382
- this.center(center.longitude, center.latitude, center.altitude * 0.5)
382
+ this.center(center.longitude, center.latitude, center.altitude * 0.8)
383
383
  },
384
384
  zoomOut () {
385
- const inertiaZoom = this.viewer.scene.screenSpaceCameraController.inertiaZoom
386
385
  const center = this.getCenter()
387
- this.center(center.longitude, center.latitude, center.altitude / 2.0)
386
+ this.center(center.longitude, center.latitude, center.altitude / 0.8)
388
387
  },
389
388
  zoomToBounds (bounds, heading = 0, pitch = -90, roll = 0, duration = 0) {
390
389
  this.viewer.camera.flyTo({
@@ -863,16 +862,26 @@ export const baseGlobe = {
863
862
  const fs = `
864
863
  uniform sampler2D colorTexture;
865
864
  in vec2 v_textureCoordinates;
865
+
866
+ uniform float desaturation;
867
+ uniform float brightness;
868
+
866
869
  void main() {
867
870
  vec4 color = texture(colorTexture, v_textureCoordinates);
868
871
  if (czm_selected()) {
869
872
  out_FragColor = color;
870
873
  } else {
871
- out_FragColor = vec4(czm_saturation(color.rgb, 0.0), color.a);
874
+ out_FragColor = vec4(czm_saturation(color.rgb, desaturation) * brightness, color.a);
872
875
  }
873
876
  }
874
877
  `
875
- stage = this.viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({ fragmentShader: fs }))
878
+ stage = this.viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({
879
+ fragmentShader: fs,
880
+ uniforms: {
881
+ desaturation: _.get(options, 'desaturation', 1.0),
882
+ brightness: _.get(options, 'brightness', 1.0)
883
+ }
884
+ }))
876
885
  stage.selected = [] // Initialize empty selected set for postprocess.
877
886
  this.cesiumPostProcessStages[effect] = stage
878
887
  }
@@ -1,9 +1,8 @@
1
- import { GeoJsonDataSource, ColorMaterialProperty, ConstantProperty, Math as CesiumMath, HeadingPitchRoll, Quaternion } from 'cesium'
1
+ import { GeoJsonDataSource, ColorMaterialProperty, ConstantProperty, Math as CesiumMath, HeadingPitchRoll, Quaternion, Cartographic, EllipsoidRhumbLine } from 'cesium'
2
2
  import _ from 'lodash'
3
3
  import logger from 'loglevel'
4
4
  import sift from 'sift'
5
5
  import { uid } from 'quasar'
6
- import { point, rhumbDistance, rhumbBearing, rhumbDestination } from '@turf/turf'
7
6
  import { Time, Units, Events } from '../../../../core.client.js'
8
7
  import { fetchGeoJson, getFeatureId, processFeatures, getFeatureStyleType, isInMemoryLayer, getGeoJsonFeatures } from '../../utils.js'
9
8
  import { convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle } from '../../utils/utils.style.js'
@@ -95,7 +94,10 @@ export const geojsonLayers = {
95
94
  entities.forEach(entity => {
96
95
  // Find matching feature if any and keep track of it as Cesium only keeps properties
97
96
  entity.feature = features.find(feature => getFeatureId(feature, options) === entity.id)
98
- const previousEntity = dataSource.entities.getById(entity.id)
97
+ let previousEntity = dataSource.entities.getById(entity.id)
98
+ CustomTypes.forEach(type => {
99
+ previousEntity = previousEntity || dataSource.entities.getById(getCustomEntityId(entity.id, type))
100
+ })
99
101
  if (previousEntity) {
100
102
  const isAnimatedLayer = _.get(updateOptions, 'duration') && _.get(entity, 'feature') && _.get(previousEntity, 'feature')
101
103
  if (isAnimatedLayer) {
@@ -328,7 +330,7 @@ export const geojsonLayers = {
328
330
  } else if (options.service) { // Check for feature service layers only, in this case update in place
329
331
  // If no probe reference, nothing to be initialized
330
332
  // Get original layer options to ensure we have the latest ones while getting features (e.g. filters toggle)
331
- await this.loadGeoJson(dataSource, this.getFeatures(Object.assign({}, options, this.getLayerByName(options.name))), options, updateOptions)
333
+ await this.loadGeoJson(dataSource, await this.getFeatures(Object.assign({}, options, this.getLayerByName(options.name))), options, updateOptions)
332
334
  } else if (sourceTemplate) {
333
335
  const sourceToFetch = dataSource.sourceCompiler({ time: Time.getCurrentTime() })
334
336
  if (!dataSource.lastFetchedSource || (dataSource.lastFetchedSource !== sourceToFetch)) {
@@ -641,32 +643,39 @@ export const geojsonLayers = {
641
643
  // Store animation information in properties so that we don't need to recompute it for next steps
642
644
  if (!currFeature.properties.animation || !currFeature.properties.animation.geometry) {
643
645
  if (!currFeature.properties.animation) currFeature.properties.animation = {}
644
- const startCoordinates = { lon: prevFeature.geometry.coordinates[0], lat: prevFeature.geometry.coordinates[1] }
645
- const endCoordinates = { lon: currFeature.geometry.coordinates[0], lat: currFeature.geometry.coordinates[1] }
646
+ const startCoordinates = { lon: prevFeature.geometry.coordinates[0], lat: prevFeature.geometry.coordinates[1], alt: prevFeature.geometry.coordinates[2] || null }
647
+ const endCoordinates = { lon: currFeature.geometry.coordinates[0], lat: currFeature.geometry.coordinates[1], alt: currFeature.geometry.coordinates[2] || null }
646
648
  currFeature.properties.animation.geometry = {
647
649
  startCoordinates,
648
650
  endCoordinates
649
651
  }
650
652
  if (animateProperty.rhumb) {
651
- const start = point([startCoordinates.lon, startCoordinates.lat])
652
- const end = point([endCoordinates.lon, endCoordinates.lat])
653
- currFeature.properties.animation.geometry.rhumb = {
654
- start,
655
- distance: rhumbDistance(start, end),
656
- bearing: rhumbBearing(start, end)
653
+ try {
654
+ const start = new Cartographic(startCoordinates.lon, startCoordinates.lat, startCoordinates.alt || 0)
655
+ const end = new Cartographic(endCoordinates.lon, endCoordinates.lat, endCoordinates.alt || 0)
656
+ currFeature.properties.animation.geometry.rhumbLine = new EllipsoidRhumbLine(start, end)
657
+ } catch (e) {
658
+ // Fallback to null if we cannot compute rhumb line (e.g. start = end)
659
+ currFeature.properties.animation.geometry.rhumbLine = null
657
660
  }
658
661
  }
659
662
  }
660
663
  // Interpolate position
661
- if (animateProperty.rhumb) {
662
- const rhumbData = currFeature.properties.animation.geometry.rhumb
663
- const destination = rhumbDestination(rhumbData.start, rhumbData.distance * tEasing, rhumbData.bearing)
664
- animatedFeature.geometry.coordinates[0] = destination.geometry.coordinates[0]
665
- animatedFeature.geometry.coordinates[1] = destination.geometry.coordinates[1]
664
+ const geometryData = currFeature.properties.animation.geometry
665
+ if (animateProperty.rhumb && currFeature.properties.animation.geometry.rhumbLine) {
666
+ const rhumbLine = currFeature.properties.animation.geometry.rhumbLine
667
+ const destination = rhumbLine.interpolateUsingFraction(tEasing, new Cartographic())
668
+ animatedFeature.geometry.coordinates[0] = destination.longitude
669
+ animatedFeature.geometry.coordinates[1] = destination.latitude
670
+ if (geometryData.startCoordinates.alt !== null && geometryData.endCoordinates.alt !== null) {
671
+ animatedFeature.geometry.coordinates[2] = destination.height
672
+ }
666
673
  } else {
667
- const geometryData = currFeature.properties.animation.geometry
668
674
  animatedFeature.geometry.coordinates[0] = lerp(geometryData.startCoordinates.lon, geometryData.endCoordinates.lon, tEasing)
669
675
  animatedFeature.geometry.coordinates[1] = lerp(geometryData.startCoordinates.lat, geometryData.endCoordinates.lat, tEasing)
676
+ if (geometryData.startCoordinates.alt !== null && geometryData.endCoordinates.alt !== null) {
677
+ animatedFeature.geometry.coordinates[2] = lerp(geometryData.startCoordinates.alt, geometryData.endCoordinates.alt, tEasing)
678
+ }
670
679
  }
671
680
  } else if (property === 'orientation') {
672
681
  // Store animation information in properties so that we don't need to recompute it for next steps
@@ -1,8 +1,10 @@
1
1
  import _ from 'lodash'
2
2
  import L from 'leaflet'
3
+ import logger from 'loglevel'
3
4
  import bearing from '@turf/bearing'
4
5
  import { getType, getCoords, getGeom } from '@turf/invariant'
5
6
  import { uid } from 'quasar'
7
+ import { Context } from '../../../../core/client/context.js'
6
8
  import { Store } from '../../../../core/client/store.js'
7
9
  import { Units } from '../../../../core/client/units.js'
8
10
  import { api } from '../../../../core/client/api.js'
@@ -98,6 +100,12 @@ export const editLayers = {
98
100
  if (!_.isEmpty(geometryTypes) && !geometryTypes.includes('Polygon') && !geometryTypes.includes('MultiPolygon')) return style(feature)
99
101
  else return getDefaultPolygonStyle(feature, layerStyle, _.get(this, 'activityOptions.engine.style.edition.polygon'))
100
102
  }
103
+ const isPoint = ((feature.geometry.type === 'Point') || (feature.geometry.type === 'MultiPoint'))
104
+ if (isPoint) {
105
+ // Skip point editing style if not editing points
106
+ if (!_.isEmpty(geometryTypes) && !geometryTypes.includes('Point') && !geometryTypes.includes('MultiPoint')) return style(feature)
107
+ else return getDefaultPointStyle(feature, layerStyle, _.get(this, 'activityOptions.engine.style.edition.point'))
108
+ }
101
109
  logger.warn(`[KDK] the geometry of type of ${feature.geometry.type} is not supported`)
102
110
  },
103
111
  pointToLayer: (feature, latlng) => {
@@ -400,7 +408,7 @@ export const editLayers = {
400
408
  layerId: this.editedLayer._id,
401
409
  layerName: this.editedLayer.name,
402
410
  featureId: feature._id,
403
- contextId: Store.get('context')
411
+ contextId: Context.get()
404
412
  })
405
413
  })
406
414
  },
@@ -4,39 +4,74 @@ import moment from 'moment'
4
4
  import sift from 'sift'
5
5
  import L from 'leaflet'
6
6
  import * as protomaps from 'protomaps-leaflet'
7
- import { mapbox_style } from '@kalisio/leaflet-pmtiles'
7
+ import { mapbox_style, kdk_style } from '@kalisio/leaflet-pmtiles'
8
8
  import { api, Time, Units, Events, TemplateContext } from '../../../../core/client/index.js'
9
+ import * as time from '../../../../core/client/utils/utils.time.js'
10
+ import * as layers from '../../utils/utils.layers.js'
11
+
12
+ function detectStyleType (style) {
13
+ // `style` field on pmtile layer definition can be one of:
14
+ // - string => in this case we assume this is a mapbox json style
15
+ // - kdk style object
16
+ // - protomaps style object
17
+
18
+ if (typeof style === 'string') return 'mapbox'
19
+ // Look for 'symbolizer' keys in the object, if we find one, this is a protomaps style
20
+ if (_.some(style, (rule) => rule.symbolizer !== undefined)) return 'protomaps'
21
+ // Otherwise we assume this is a kdk style object
22
+ return style ? 'kdk' : 'empty'
23
+ }
9
24
 
10
25
  export const pmtilesLayers = {
11
26
  methods: {
12
- async createLeafletPMTilesLayer (options) {
27
+ async processLeafletPMTilesLayer (options, properties = ['urlTemplate', 'styleTemplate', 'template']) {
13
28
  const leafletOptions = options.leaflet || options
14
- // Check for valid types
15
- if (leafletOptions.type !== 'pmtiles') return
16
-
29
+
17
30
  // Token required by templating
18
31
  const planetApi = (typeof options.getPlanetApi === 'function' ? options.getPlanetApi() : api)
19
32
  const apiJwt = (planetApi.hasConfig('apiJwt') ? await planetApi.get('storage').getItem(planetApi.getConfig('apiJwt')) : null)
20
33
  const gatewayJwt = (planetApi.hasConfig('gatewayJwt') ? await planetApi.get('storage').getItem(planetApi.getConfig('gatewayJwt')) : null)
21
34
 
22
- const urlTemplate = _.get(leafletOptions, 'urlTemplate')
23
- if (urlTemplate) leafletOptions.url = _.template(urlTemplate)({ apiJwt, gatewayJwt })
24
- const styleTemplate = _.get(leafletOptions, 'styleTemplate')
25
- if (styleTemplate) leafletOptions.style = _.template(styleTemplate)({ apiJwt, gatewayJwt })
26
-
27
- // Optimize templating by creating compilers up-front
28
- const layerStyleTemplate = _.get(leafletOptions, 'template')
29
- if (layerStyleTemplate) {
30
- // We allow to template style properties according to feature, because it can be slow you have to specify a subset of properties
31
- leafletOptions.template = layerStyleTemplate.map(property => ({
32
- property, compiler: _.template(_.get(leafletOptions, property))
33
- }))
35
+ if (properties.includes('urlTemplate')) {
36
+ const urlTemplate = _.get(leafletOptions, 'urlTemplate')
37
+ if (urlTemplate) {
38
+ const context = Object.assign({
39
+ apiJwt, gatewayJwt, moment, Units, Time, level: this.selectedLevel, ...time
40
+ }, TemplateContext.get())
41
+ leafletOptions.url = _.template(urlTemplate)(context)
42
+ }
34
43
  }
35
-
44
+ if (properties.includes('styleTemplate')) {
45
+ const styleTemplate = _.get(leafletOptions, 'styleTemplate')
46
+ if (styleTemplate) {
47
+ const context = Object.assign({
48
+ apiJwt, gatewayJwt, moment, Units, Time, level: this.selectedLevel, ...time
49
+ }, TemplateContext.get())
50
+ leafletOptions.style = _.template(styleTemplate)(context)
51
+ }
52
+ }
53
+ if (properties.includes('template')) {
54
+ // Optimize templating by creating compilers up-front
55
+ const layerStyleTemplate = _.get(leafletOptions, 'template')
56
+ if (layerStyleTemplate) {
57
+ // We allow to template style properties according to feature, because it can be slow you have to specify a subset of properties
58
+ leafletOptions.template = layerStyleTemplate.map(property => ({
59
+ property, compiler: _.template(_.get(leafletOptions, property))
60
+ }))
61
+ }
62
+ }
63
+ },
64
+ async createLeafletPMTilesLayer (options) {
65
+ const leafletOptions = options.leaflet || options
66
+ // Check for valid types
67
+ if (leafletOptions.type !== 'pmtiles') return
68
+ // Process main options
69
+ await this.processLeafletPMTilesLayer(options)
70
+ // Then create rendering rules
36
71
  let rules = {}
37
- // Check for style information given as object or URL
38
72
  let style = _.get(leafletOptions, 'style')
39
- if (typeof style === 'string') {
73
+ const styleType = detectStyleType(style)
74
+ if (styleType === 'mapbox') {
40
75
  const response = await fetch(style)
41
76
  if (response.status !== 200) {
42
77
  throw new Error(`Impossible to fetch style ${style}: ` + response.status)
@@ -48,24 +83,49 @@ export const pmtilesLayers = {
48
83
  rules = mapbox_style(style, {})
49
84
  } else {
50
85
  // Manage templating
51
- _.get(leafletOptions, 'template', []).forEach(entry => {
52
- // protomaps allows property functions with zomm/feature as input
86
+ const templates = _.get(leafletOptions, 'template', [])
87
+ templates.forEach(entry => {
88
+ // protomaps allows property functions with zoom/feature as input
53
89
  const f = (zoom, feature) => {
54
90
  const context = Object.assign({ properties: feature.props, feature, chroma, moment, Units, Time, level: this.selectedLevel }, TemplateContext.get())
55
- return entry.property.endsWith('filter') ? (entry.compiler(context) === 'true'): entry.compiler(context)
91
+ if (entry.property.endsWith('filter')) {
92
+ const result = entry.compiler(context)
93
+ return (result === 'true')
94
+ } else {
95
+ return entry.compiler(context)
96
+ }
56
97
  }
57
98
  _.set(leafletOptions, entry.property, f)
58
99
  })
59
- if (style) {
100
+ if (styleType === 'protomaps') {
60
101
  const styleRules = _.map(style, rule => Object.assign(_.omit(rule, ['symbolizer']), {
61
- symbolizer: new protomaps[rule.symbolizer.type](rule.symbolizer)
62
- })
102
+ symbolizer: new protomaps[rule.symbolizer.type](rule.symbolizer)
103
+ })
63
104
  )
64
105
  const isLabelSymbolizer = (rule) => typeof rule.symbolizer.place === 'function'
65
106
  const isNotLabelSymbolizer = (rule) => !isLabelSymbolizer(rule)
66
107
  // Support v1.x as well as v2.x
67
108
  rules.paint_rules = rules.paintRules = _.filter(styleRules, isNotLabelSymbolizer)
68
109
  rules.label_rules = rules.labelRules = _.filter(styleRules, isLabelSymbolizer)
110
+ } else if (styleType === 'kdk') {
111
+ // Translate kdk style to protomap rules
112
+ rules = kdk_style(style, leafletOptions.dataLayer)
113
+ }
114
+ if (options.filters) {
115
+ // Translate layer filters to filter function
116
+ const filterFn = layers.getFilterFunctionFromLayerFilters(options)
117
+ rules.paintRules.forEach(rule => {
118
+ // kdkFilter member may not be present, this is added by kdk_style when translating kdk style
119
+ // to leaflet-protomaps rules
120
+ if (rule.kdkFilter) {
121
+ rule.filter = (zoom, feature) => {
122
+ // Final filter = kdk style filter + updated filter
123
+ return rule.kdkFilter(zoom, feature) && filterFn({ zoom, feature, properties: feature.props })
124
+ }
125
+ } else {
126
+ rule.filter = (zoom, feature) => filterFn({ zoom, feature, properties: feature.props })
127
+ }
128
+ })
69
129
  }
70
130
  }
71
131
 
@@ -82,9 +142,16 @@ export const pmtilesLayers = {
82
142
  // Skip invisible layers
83
143
  isVisible: true
84
144
  }))
85
- pmtileslayers.forEach(async pmtileslayer => {
145
+ pmtileslayers.forEach(async pmtilesLayer => {
86
146
  // Retrieve the layer
87
- const layer = this.getLeafletLayerByName(pmtileslayer.name)
147
+ const layer = this.getLeafletLayerByName(pmtilesLayer.name)
148
+ const leafletOptions = pmtilesLayer.leaflet || pmtilesLayer
149
+ const urlTemplate = _.get(leafletOptions, 'urlTemplate')
150
+ if (urlTemplate) {
151
+ await this.processLeafletPMTilesLayer(pmtilesLayer, ['urlTemplate'])
152
+ // Need to update underlying PMTiles source
153
+ layer.views = protomaps.sourcesToViews(leafletOptions)
154
+ }
88
155
  layer.redraw()
89
156
  })
90
157
  },
@@ -100,20 +167,42 @@ export const pmtilesLayers = {
100
167
  layer.redraw()
101
168
  }
102
169
  }
170
+ },
171
+ onLayerFilterToggledPMTilesLayers (layer, filter) {
172
+ // Filtering is managed by mongodb query syntax, we need to update the filter function
173
+ const filterFn = layers.getFilterFunctionFromLayerFilters(layer)
174
+ // Retrieve the engine layer and update the filter function directly
175
+ layer = this.getLeafletLayerByName(layer. name)
176
+ if (!layer) return
177
+ layer.paintRules.forEach(rule => {
178
+ // kdkFilter member may not be present, this is added by kdk_style when translating kdk style
179
+ // to leaflet-protomaps rules
180
+ if (rule.kdkFilter) {
181
+ rule.filter = (zoom, feature) => {
182
+ // Final filter = kdk style filter + updated filter
183
+ return rule.kdkFilter(zoom, feature) && filterFn({ zoom, feature, properties: feature.props })
184
+ }
185
+ } else {
186
+ rule.filter = (zoom, feature) => filterFn({ zoom, feature, properties: feature.props })
187
+ }
188
+ })
189
+ layer.redraw()
103
190
  }
104
191
  },
105
192
  created () {
106
193
  this.registerLeafletConstructor(this.createLeafletPMTilesLayer)
107
194
  Events.on('time-current-time-changed', this.onCurrentTimeChangedPMTilesLayers)
108
195
  this.$engineEvents.on('selected-level-changed', this.onCurrentLevelChangedPMTilesLayers)
196
+ this.$engineEvents.on('layer-filter-toggled', this.onLayerFilterToggledPMTilesLayers)
109
197
  },
110
198
  beforeUnmount () {
111
199
  Events.off('time-current-time-changed', this.onCurrentTimeChangedPMTilesLayers)
112
200
  this.$engineEvents.off('selected-level-changed', this.onCurrentLevelChangedPMTilesLayers)
201
+ this.$engineEvents.off('layer-filter-toggled', this.onLayerFilterToggledPMTilesLayers)
113
202
  }
114
203
  }
115
204
 
116
205
  // Not automatically declared by leaflet plugin
117
206
  L.pmtiles = function (options) {
118
207
  return protomaps.leafletLayer(options)
119
- }
208
+ }
@@ -1,6 +1,8 @@
1
1
  import _ from 'lodash'
2
+ import moment from 'moment'
2
3
  import { Time } from '../../../../core/client/time.js'
3
4
  import { Events } from '../../../../core/client/events.js'
5
+ import * as time from '../../../../core/client/utils/utils.time.js'
4
6
  import { makeGridSource, extractGridSourceConfig } from '../../../common/grid.js'
5
7
  import { TiledMeshLayer } from '../../leaflet/TiledMeshLayer.js'
6
8
 
@@ -18,14 +20,19 @@ export const tiledMeshLayers = {
18
20
 
19
21
  // Build grid source
20
22
  const [gridKey, gridConf] = extractGridSourceConfig(options)
21
- const weacastApi = (typeof options.getPlanetApi === 'function' ? options.getPlanetApi() : this.getWeacastApi())
22
- const apiToken = (weacastApi.hasConfig('gatewayJwt') ? await weacastApi.get('storage').getItem(weacastApi.getConfig('gatewayJwt')) : null)
23
- const gridSource = makeGridSource(gridKey, { weacastApi, apiToken })
23
+ const planetApi = (typeof options.getPlanetApi === 'function' ? options.getPlanetApi() : this.getWeacastApi())
24
+ const apiJwt = (planetApi.hasConfig('apiJwt') ? await planetApi.get('storage').getItem(planetApi.getConfig('apiJwt')) : null)
25
+ const gatewayJwt = (planetApi.hasConfig('gatewayJwt') ? await planetApi.get('storage').getItem(planetApi.getConfig('gatewayJwt')) : null)
26
+ const gridSource = makeGridSource(gridKey, { planetApi })
24
27
  gridSource.setup(gridConf)
25
28
  if (gridSource.updateCtx) {
26
29
  // define variables for source's dynamic properties
27
- if (apiToken) gridSource.updateCtx.jwtToken = apiToken
28
- gridSource.updateCtx.meteoElements = _.get(options, 'meteoElements')
30
+ Object.assign(gridSource.updateCtx, {
31
+ apiJwt, gatewayJwt, moment, Time, ...time,
32
+ // This one is for backward compatibility
33
+ jwtToken: gatewayJwt,
34
+ meteoElements: _.get(options, 'meteoElements')
35
+ })
29
36
  }
30
37
 
31
38
  return new TiledMeshLayer(layerOptions, gridSource)
@@ -1,7 +1,9 @@
1
1
  import _ from 'lodash'
2
+ import moment from 'moment'
2
3
  import 'leaflet-velocity'
3
4
  import { Time } from '../../../../core/client/time.js'
4
5
  import { Events } from '../../../../core/client/events.js'
6
+ import * as time from '../../../../core/client/utils/utils.time.js'
5
7
  import { makeGridSource, extractGridSourceConfig } from '../../../common/grid.js'
6
8
  import { TiledWindLayer } from '../../leaflet/TiledWindLayer.js'
7
9
 
@@ -20,20 +22,27 @@ export const tiledWindLayers = {
20
22
  // Build u & v grid sources
21
23
  const [gridKey, gridConf] = extractGridSourceConfig(options)
22
24
  // Check API to be used in case the layer is coming from a remote "planet"
23
- const weacastApi = (typeof options.getPlanetApi === 'function' ? options.getPlanetApi() : this.getWeacastApi())
24
- const uSource = makeGridSource(gridKey, { weacastApi })
25
- const vSource = makeGridSource(gridKey, { weacastApi })
25
+ const planetApi = (typeof options.getPlanetApi === 'function' ? options.getPlanetApi() : this.getWeacastApi())
26
+ const uSource = makeGridSource(gridKey, { planetApi })
27
+ const vSource = makeGridSource(gridKey, { planetApi })
26
28
  uSource.setup(gridConf)
27
29
  vSource.setup(gridConf)
28
30
  if (uSource.updateCtx) {
29
31
  // define variables for source's dynamic properties
30
- const gatewayToken = (weacastApi.hasConfig('gatewayJwt') ? await weacastApi.get('storage').getItem(weacastApi.getConfig('gatewayJwt')) : null)
31
- if (gatewayToken) {
32
- uSource.updateCtx.jwtToken = gatewayToken
33
- vSource.updateCtx.jwtToken = gatewayToken
34
- }
35
- uSource.updateCtx.windComponent = _.get(options, 'meteoElements[0]')
36
- vSource.updateCtx.windComponent = _.get(options, 'meteoElements[1]')
32
+ const apiJwt = (planetApi.hasConfig('apiJwt') ? await planetApi.get('storage').getItem(planetApi.getConfig('apiJwt')) : null)
33
+ const gatewayJwt = (planetApi.hasConfig('gatewayJwt') ? await planetApi.get('storage').getItem(planetApi.getConfig('gatewayJwt')) : null)
34
+ Object.assign(uSource.updateCtx, {
35
+ apiJwt, gatewayJwt, moment, Time, ...time,
36
+ // This one is for backward compatibility
37
+ jwtToken: gatewayJwt,
38
+ windComponent: _.get(options, 'meteoElements[0]')
39
+ })
40
+ Object.assign(vSource.updateCtx, {
41
+ apiJwt, gatewayJwt, ...time,
42
+ // This one is for backward compatibility
43
+ jwtToken: gatewayJwt,
44
+ windComponent: _.get(options, 'meteoElements[1]')
45
+ })
37
46
  }
38
47
 
39
48
  return new TiledWindLayer(layerOptions, uSource, vSource)
@@ -2,7 +2,7 @@ import config from 'config'
2
2
  import _ from 'lodash'
3
3
  import logger from 'loglevel'
4
4
  import sift from 'sift'
5
- import { Store } from '../../../core/client/store.js'
5
+ import { Context } from '../../../core/client/context.js'
6
6
  import { Events } from '../../../core/client/events.js'
7
7
  import { api } from '../../../core/client/api.js'
8
8
  import { isDataOperation } from '../../../core/client/utils/utils.services.js'
@@ -50,19 +50,11 @@ export const activity = {
50
50
  return []
51
51
  },
52
52
  async getCatalogLayers () {
53
- const query = {}
54
- // Do we get layers coming from project ?
55
- if (this.project) {
56
- Object.assign(query, this.catalogProjectQuery ? this.catalogProjectQuery : getCatalogProjectQuery(this.project))
57
- } else {
58
- this.project = null
59
- }
60
-
53
+ const context = Context.get()
61
54
  // We get layers coming from global catalog first if any
62
- let layers = await getLayers({ query })
55
+ let layers = await getLayers({ context: 'global', project: this.project })
63
56
  // Then we get layers coming from contextual catalog if any
64
- const context = Store.get('context')
65
- if (context) layers = layers.concat(await getLayers({ query, context }))
57
+ if (context) layers = layers.concat(await getLayers({ context, project: this.project }))
66
58
  return layers
67
59
  },
68
60
  async addCatalogLayer (layer) {
@@ -86,18 +78,18 @@ export const activity = {
86
78
  },
87
79
  async getCatalogCategories () {
88
80
  // We get categories coming from global catalog first if any
89
- let categories = await getCategories()
81
+ let categories = await getCategories({ context: 'global', project: this.project })
90
82
  // Then we get categories coming from contextual catalog if any
91
- const context = Store.get('context')
92
- if (context) categories = categories.concat(await getCategories({ context }))
83
+ const context = Context.get()
84
+ if (context) categories = categories.concat(await getCategories({ context, project: this.project }))
93
85
  return categories
94
86
  },
95
87
  async getCatalogSublegends () {
96
88
  // We get sublegends coming from global catalog first if any
97
- let sublegends = await getSublegends()
89
+ let sublegends = await getSublegends({ context: 'global', project: this.project })
98
90
  // 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 }))
91
+ const context = Context.get()
92
+ if (context) sublegends = sublegends.concat(await getSublegends({ context, project: this.project }))
101
93
  return sublegends
102
94
  },
103
95
  async addCatalogCategory (category) {
@@ -110,7 +102,8 @@ export const activity = {
110
102
  for (let i = 0; i < layerCategories.length; i++) {
111
103
  this.addCatalogCategory(layerCategories[i])
112
104
  }
113
- await this.refreshOrphanLayers()
105
+ // Update orphan layers list (ie layers without any category) based on current loaded categories/layers
106
+ this.orphanLayers = await this.getOrphanLayers()
114
107
  this.reorderLayers()
115
108
  },
116
109
  getOrphanLayerByName (name) {
@@ -162,7 +155,8 @@ export const activity = {
162
155
  for (let i = 0; i < catalogLayers.length; i++) {
163
156
  await this.addCatalogLayer(catalogLayers[i])
164
157
  }
165
- await this.refreshOrphanLayers()
158
+ // Update orphan layers list (ie layers without any category) based on current loaded categories/layers
159
+ this.orphanLayers = await this.getOrphanLayers()
166
160
  // We need at least an active background
167
161
  const hasVisibleBaseLayer = catalogLayers.find((layer) => (layer.type === 'BaseLayer') && layer.isVisible)
168
162
  if (!hasVisibleBaseLayer) {
@@ -171,10 +165,9 @@ export const activity = {
171
165
  }
172
166
  this.reorderLayers()
173
167
  },
174
- // Update orphan layers list (ie layers without any category) based on current loaded categories/layers
175
- async refreshOrphanLayers () {
168
+ async getOrphanLayers () {
176
169
  const layersByCategory = getLayersByCategory(this.layers, this.layerCategories)
177
- this.orphanLayers = getOrphanLayers(this.layers, layersByCategory)
170
+ return getOrphanLayers(this.layers, layersByCategory)
178
171
  },
179
172
  isInMemoryLayer: layers.isInMemoryLayer,
180
173
  isUserLayer: layers.isUserLayer,
@@ -322,9 +315,6 @@ export const activity = {
322
315
  await this.resetLayer(layer)
323
316
  }
324
317
  },
325
- async onRemoveCategory (category) {
326
- // virtual method
327
- },
328
318
  async onRemoveLayer (layer) {
329
319
  // Stop any running edition
330
320
  if ((typeof this.isLayerEdited === 'function') && this.isLayerEdited(layer)) await this.stopEditLayer('reject')
@@ -336,11 +326,10 @@ export const activity = {
336
326
  // Removing the layer should automatically update all projects
337
327
  },
338
328
  async onAddOrphanLayer (layer) {
339
- if (!this.isOrphanLayer(layer)) {
340
- await this.refreshOrphanLayers()
341
- }
329
+ // FIXME: Not easy to detect if the new layer will be orphan except by recomputing everything
330
+ this.orphanLayers = await this.getOrphanLayers()
342
331
  },
343
- onRemoveOrphanLayer (layer) {
332
+ async onRemoveOrphanLayer (layer) {
344
333
  if (this.isOrphanLayer(layer)) {
345
334
  _.remove(this.orphanLayers, orphanLayer => layer._id ? orphanLayer._id === layer._id : orphanLayer.name === layer.name)
346
335
  }
@@ -420,6 +409,8 @@ export const activity = {
420
409
  if (layer && (typeof layer.getPlanetApi === 'function')) {
421
410
  planetApi = layer.getPlanetApi()
422
411
  }
412
+ // Check if layer was visible before refreshing it
413
+ const isVisibleBeforeRefresh = this.isLayerVisible(layer.name)
423
414
  if (layer) {
424
415
  // Stop any running edition
425
416
  if ((typeof this.isLayerEdited === 'function') && this.isLayerEdited(layer)) await this.stopEditLayer('reject')
@@ -439,6 +430,8 @@ export const activity = {
439
430
  await setEngineJwt([layer], planetApi)
440
431
  processTranslations(layer)
441
432
  await this.addCatalogLayer(layer)
433
+ // Check if not already visible, because addCatalogLayer might have shown it in some cases
434
+ if (isVisibleBeforeRefresh && !this.isLayerVisible(layer.name)) await this.showLayer(layer.name)
442
435
  }
443
436
  },
444
437
  requestRefreshLayer (layer, event) {