@kalisio/kdk 2.6.4 → 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 (398) 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 +392 -398
  69. package/coverage/core/api/authentication.js.html +352 -187
  70. package/coverage/core/api/db.js.html +165 -126
  71. package/coverage/core/api/hooks/hooks.authentication.js.html +22 -196
  72. package/coverage/core/api/hooks/hooks.authorisations.js.html +383 -662
  73. package/coverage/core/api/hooks/hooks.logger.js.html +41 -41
  74. package/coverage/core/api/hooks/hooks.model.js.html +113 -101
  75. package/coverage/core/api/hooks/hooks.push.js.html +124 -97
  76. package/coverage/core/api/hooks/hooks.query.js.html +292 -217
  77. package/coverage/core/api/hooks/hooks.schemas.js.html +123 -123
  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.groups.js.html → hooks.tags.js.html} +100 -76
  81. package/coverage/core/api/hooks/hooks.users.js.html +255 -447
  82. package/coverage/core/api/hooks/index.html +107 -122
  83. package/coverage/core/api/hooks/index.js.html +4 -10
  84. package/coverage/core/api/index.html +46 -61
  85. package/coverage/core/api/index.js.html +9 -9
  86. package/coverage/core/api/marshall.js.html +9 -9
  87. package/coverage/core/api/models/{organisations.model.mongodb.js.html → configurations.model.mongodb.js.html} +10 -7
  88. package/coverage/core/api/models/index.html +35 -50
  89. package/coverage/core/api/models/messages.model.mongodb.js.html +39 -27
  90. package/coverage/core/api/models/tags.model.mongodb.js.html +26 -32
  91. package/coverage/core/api/models/users.model.mongodb.js.html +10 -10
  92. package/coverage/core/api/services/account/account.hooks.js.html +5 -5
  93. package/coverage/core/api/services/account/account.service.js.html +127 -127
  94. package/coverage/core/api/services/account/index.html +22 -22
  95. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
  96. package/coverage/core/api/services/authorisations/authorisations.service.js.html +213 -222
  97. package/coverage/core/api/services/authorisations/index.html +21 -21
  98. package/coverage/core/api/services/{organisations/organisations.hooks.js.html → configurations/configurations.hooks.js.html} +16 -10
  99. package/coverage/core/api/services/{groups → configurations}/index.html +8 -8
  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 +76 -76
  104. package/coverage/core/api/services/import-export/import-export.service.js.html +32 -32
  105. package/coverage/core/api/services/import-export/index.html +32 -32
  106. package/coverage/core/api/services/index.html +21 -21
  107. package/coverage/core/api/services/index.js.html +313 -142
  108. package/coverage/core/api/services/mailer/index.html +32 -32
  109. package/coverage/core/api/services/mailer/mailer.hooks.js.html +80 -80
  110. package/coverage/core/api/services/mailer/mailer.service.js.html +32 -32
  111. package/coverage/core/api/services/messages/index.html +21 -21
  112. package/coverage/core/api/services/messages/messages.hooks.js.html +112 -76
  113. package/coverage/core/api/services/push/index.html +32 -32
  114. package/coverage/core/api/services/push/push.hooks.js.html +80 -80
  115. package/coverage/core/api/services/push/push.service.js.html +34 -34
  116. package/coverage/core/api/services/storage/index.html +29 -29
  117. package/coverage/core/api/services/storage/storage.hooks.js.html +80 -80
  118. package/coverage/core/api/services/storage/storage.service.js.html +29 -29
  119. package/coverage/core/api/services/tags/index.html +21 -21
  120. package/coverage/core/api/services/tags/tags.hooks.js.html +119 -71
  121. package/coverage/core/api/services/users/index.html +27 -12
  122. package/coverage/core/api/services/users/users.hooks.js.html +14 -11
  123. package/coverage/core/api/services/users/users.service.js.html +100 -0
  124. package/coverage/core/common/errors.js.html +1 -1
  125. package/coverage/core/common/index.html +42 -27
  126. package/coverage/core/common/index.js.html +1 -1
  127. package/coverage/core/common/permissions.js.html +166 -472
  128. package/coverage/core/common/schema.js.html +4 -4
  129. package/coverage/core/common/utils.js.html +31 -25
  130. package/coverage/core/common/utils.offline.js.html +199 -0
  131. package/coverage/index.html +192 -192
  132. package/coverage/lcov-report/core/api/application.js.html +392 -398
  133. package/coverage/lcov-report/core/api/authentication.js.html +352 -187
  134. package/coverage/lcov-report/core/api/db.js.html +165 -126
  135. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +22 -196
  136. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +383 -662
  137. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +41 -41
  138. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +113 -101
  139. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +124 -97
  140. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +292 -217
  141. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +123 -123
  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.groups.js.html → hooks.tags.js.html} +100 -76
  145. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +255 -447
  146. package/coverage/lcov-report/core/api/hooks/index.html +107 -122
  147. package/coverage/lcov-report/core/api/hooks/index.js.html +4 -10
  148. package/coverage/lcov-report/core/api/index.html +46 -61
  149. package/coverage/lcov-report/core/api/index.js.html +9 -9
  150. package/coverage/lcov-report/core/api/marshall.js.html +9 -9
  151. package/coverage/lcov-report/core/api/models/{organisations.model.mongodb.js.html → configurations.model.mongodb.js.html} +10 -7
  152. package/coverage/lcov-report/core/api/models/index.html +35 -50
  153. package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +39 -27
  154. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +26 -32
  155. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +10 -10
  156. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +5 -5
  157. package/coverage/lcov-report/core/api/services/account/account.service.js.html +127 -127
  158. package/coverage/lcov-report/core/api/services/account/index.html +22 -22
  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 +213 -222
  161. package/coverage/lcov-report/core/api/services/authorisations/index.html +21 -21
  162. package/coverage/lcov-report/core/api/services/{groups/groups.hooks.js.html → configurations/configurations.hooks.js.html} +16 -10
  163. package/coverage/lcov-report/core/api/services/{groups → configurations}/index.html +8 -8
  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 +76 -76
  168. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +32 -32
  169. package/coverage/lcov-report/core/api/services/import-export/index.html +32 -32
  170. package/coverage/lcov-report/core/api/services/index.html +21 -21
  171. package/coverage/lcov-report/core/api/services/index.js.html +313 -142
  172. package/coverage/lcov-report/core/api/services/mailer/index.html +32 -32
  173. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +80 -80
  174. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +32 -32
  175. package/coverage/lcov-report/core/api/services/messages/index.html +21 -21
  176. package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +112 -76
  177. package/coverage/lcov-report/core/api/services/push/index.html +32 -32
  178. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +80 -80
  179. package/coverage/lcov-report/core/api/services/push/push.service.js.html +34 -34
  180. package/coverage/lcov-report/core/api/services/storage/index.html +29 -29
  181. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +80 -80
  182. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +29 -29
  183. package/coverage/lcov-report/core/api/services/tags/index.html +21 -21
  184. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +119 -71
  185. package/coverage/lcov-report/core/api/services/users/index.html +27 -12
  186. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +14 -11
  187. package/coverage/lcov-report/core/api/services/users/users.service.js.html +100 -0
  188. package/coverage/lcov-report/core/common/errors.js.html +1 -1
  189. package/coverage/lcov-report/core/common/index.html +42 -27
  190. package/coverage/lcov-report/core/common/index.js.html +1 -1
  191. package/coverage/lcov-report/core/common/permissions.js.html +166 -472
  192. package/coverage/lcov-report/core/common/schema.js.html +4 -4
  193. package/coverage/lcov-report/core/common/utils.js.html +31 -25
  194. package/coverage/lcov-report/core/common/utils.offline.js.html +199 -0
  195. package/coverage/lcov-report/index.html +192 -192
  196. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +169 -31
  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 +215 -35
  199. package/coverage/lcov-report/map/api/hooks/index.html +7 -7
  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 +82 -7
  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 +22 -7
  208. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +1 -1
  209. package/coverage/lcov-report/{core/api/models/groups.model.mongodb.js.html → map/api/models/styles.model.mongodb.js.html} +10 -7
  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 +39 -12
  214. package/coverage/lcov-report/map/api/services/catalog/index.html +5 -5
  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 +86 -11
  218. package/coverage/lcov-report/map/api/services/features/features.service.js.html +307 -4
  219. package/coverage/lcov-report/map/api/services/features/index.html +7 -7
  220. package/coverage/lcov-report/map/api/services/index.html +5 -5
  221. package/coverage/lcov-report/map/api/services/index.js.html +326 -50
  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/{core/api/services/organisations → lcov-report/map/api/services/styles}/index.html +10 -25
  225. package/coverage/lcov-report/{core/api/services/organisations/organisations.hooks.js.html → map/api/services/styles/styles.hooks.js.html} +45 -12
  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 +7 -10
  229. package/coverage/lcov-report/map/common/grid.js.html +1 -1
  230. package/coverage/lcov-report/map/common/index.html +19 -19
  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 +4 -7
  236. package/coverage/lcov-report/map/common/permissions.js.html +10 -4
  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 +9 -12
  239. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +3 -3
  240. package/coverage/lcov-report/map/common/wcs-utils.js.html +12 -15
  241. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +2 -2
  242. package/coverage/lcov-report/map/common/wfs-utils.js.html +14 -17
  243. package/coverage/lcov-report/map/common/wms-utils.js.html +30 -12
  244. package/coverage/lcov-report/map/common/wmts-utils.js.html +10 -13
  245. package/coverage/lcov.info +4157 -3816
  246. package/coverage/map/api/hooks/hooks.catalog.js.html +169 -31
  247. package/coverage/map/api/hooks/hooks.features.js.html +1 -1
  248. package/coverage/map/api/hooks/hooks.query.js.html +215 -35
  249. package/coverage/map/api/hooks/index.html +7 -7
  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 +82 -7
  256. package/coverage/map/api/models/features.model.mongodb.js.html +1 -1
  257. package/coverage/map/api/models/index.html +22 -7
  258. package/coverage/map/api/models/projects.model.mongodb.js.html +1 -1
  259. package/coverage/{core/api/models/groups.model.mongodb.js.html → map/api/models/styles.model.mongodb.js.html} +10 -7
  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 +39 -12
  264. package/coverage/map/api/services/catalog/index.html +5 -5
  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 +86 -11
  268. package/coverage/map/api/services/features/features.service.js.html +307 -4
  269. package/coverage/map/api/services/features/index.html +7 -7
  270. package/coverage/map/api/services/index.html +5 -5
  271. package/coverage/map/api/services/index.js.html +326 -50
  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/{lcov-report/core/api/services/organisations → map/api/services/styles}/index.html +10 -25
  275. package/coverage/{core/api/services/groups/groups.hooks.js.html → map/api/services/styles/styles.hooks.js.html} +45 -12
  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 +7 -10
  279. package/coverage/map/common/grid.js.html +1 -1
  280. package/coverage/map/common/index.html +19 -19
  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 +4 -7
  286. package/coverage/map/common/permissions.js.html +10 -4
  287. package/coverage/map/common/time-based-grid-source.js.html +1 -1
  288. package/coverage/map/common/tms-utils.js.html +9 -12
  289. package/coverage/map/common/wcs-grid-source.js.html +3 -3
  290. package/coverage/map/common/wcs-utils.js.html +12 -15
  291. package/coverage/map/common/weacast-grid-source.js.html +2 -2
  292. package/coverage/map/common/wfs-utils.js.html +14 -17
  293. package/coverage/map/common/wms-utils.js.html +30 -12
  294. package/coverage/map/common/wmts-utils.js.html +10 -13
  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-1028556-1773134124353-0.json +1 -0
  300. package/extras/configs/widgets.top.js +3 -3
  301. package/extras/tests/core/collection.mjs +2 -9
  302. package/extras/tours/pane.top.js +0 -9
  303. package/map/api/hooks/hooks.catalog.js +18 -4
  304. package/map/api/services/catalog/catalog.hooks.js +3 -0
  305. package/map/api/services/features/features.hooks.js +3 -1
  306. package/map/api/services/index.js +2 -6
  307. package/map/api/services/styles/styles.hooks.js +6 -1
  308. package/map/client/components/KFeatureActionButton.vue +9 -3
  309. package/map/client/components/KFeaturesFilterManager.vue +5 -5
  310. package/map/client/components/KFilterCondition.vue +17 -10
  311. package/map/client/components/KLayerEditor.vue +49 -39
  312. package/map/client/components/KMeasureTool.vue +7 -1
  313. package/map/client/components/KTimezoneMap.vue +29 -9
  314. package/map/client/components/catalog/KLayersPanel.vue +26 -16
  315. package/map/client/components/catalog/KLayersSelector.vue +13 -2
  316. package/map/client/components/catalog/KViewsPanel.vue +5 -4
  317. package/map/client/components/form/KSelectLayersField.vue +28 -17
  318. package/map/client/components/form/KSelectViewsField.vue +18 -9
  319. package/map/client/components/form/KTimezoneField.vue +1 -2
  320. package/map/client/components/legend/KVariablesLegend.vue +10 -1
  321. package/map/client/components/location/KLocationCardSection.vue +7 -2
  322. package/map/client/components/location/KLocationMap.vue +31 -7
  323. package/map/client/components/selection/KSelectedLayerFeatures.vue +2 -2
  324. package/map/client/components/stickies/KZoomControl.vue +1 -1
  325. package/map/client/components/styles/KStyleManager.vue +4 -1
  326. package/map/client/components/widget/KTimeSeries.vue +174 -497
  327. package/map/client/components/widget/KTimeSeriesSelector.vue +72 -0
  328. package/map/client/components/widget/KTimeSeriesToolbar.vue +83 -0
  329. package/map/client/composables/catalog.js +6 -10
  330. package/map/client/composables/highlight.js +12 -9
  331. package/map/client/composables/project.js +1 -1
  332. package/map/client/composables/selection.js +8 -7
  333. package/map/client/composables/weather.js +9 -2
  334. package/map/client/geolocation.js +8 -5
  335. package/map/client/i18n/map_en.json +11 -10
  336. package/map/client/i18n/map_fr.json +10 -9
  337. package/map/client/leaflet/TiledFeatureLayer.js +85 -82
  338. package/map/client/leaflet/utils/utils.geojson.js +3 -3
  339. package/map/client/mixins/globe/mixin.base-globe.js +15 -6
  340. package/map/client/mixins/globe/mixin.geojson-layers.js +27 -18
  341. package/map/client/mixins/map/mixin.edit-layers.js +9 -1
  342. package/map/client/mixins/map/mixin.pmtiles-layers.js +118 -29
  343. package/map/client/mixins/map/mixin.tiled-mesh-layers.js +12 -5
  344. package/map/client/mixins/map/mixin.tiled-wind-layers.js +19 -10
  345. package/map/client/mixins/mixin.activity.js +23 -30
  346. package/map/client/mixins/mixin.feature-selection.js +41 -5
  347. package/map/client/planets.js +1 -1
  348. package/map/client/readers/reader.kml.js +2 -3
  349. package/map/client/utils/utils.catalog.js +36 -10
  350. package/map/client/utils/utils.layers.js +39 -8
  351. package/map/client/utils/utils.project.js +4 -0
  352. package/map/client/utils/utils.style.js +37 -7
  353. package/map/client/utils/utils.time-series.js +215 -6
  354. package/map/common/schemas/catalog.update.json +1 -1
  355. package/map/common/weacast-grid-source.js +1 -1
  356. package/package.json +3 -3
  357. package/scripts/kash/CHANGELOG.md +0 -4
  358. package/scripts/kash/README.md +0 -9
  359. package/scripts/kash/kash.sh +45 -40
  360. package/scripts/kash/scripts/run_tests.sh +1 -4
  361. package/test/api/core/authentication.test.js +9 -4
  362. package/test/api/core/config/default.cjs +1 -0
  363. package/test/api/core/hooks.test.js +6 -0
  364. package/test/api/core/index.test.js +43 -18
  365. package/test/api/core/push.test.js +8 -8
  366. package/test/api/core/test-log-2026-03-10.log +60 -0
  367. package/test/api/core/users.test.js +384 -0
  368. package/test/api/map/grid-sources.test.js +1 -1
  369. package/test/api/map/test-log-2026-03-10.log +56 -0
  370. package/vite/package.json +11 -2
  371. package/vite/test/core/composables.test.js +77 -0
  372. package/vite/vitest.config.js +13 -0
  373. package/vite/yarn.lock +1096 -18
  374. package/.vscode/settings.json +0 -5
  375. package/core/client/components/account/KAccount.vue +0 -68
  376. package/core/client/components/account/KDeleteAccountManager.vue +0 -62
  377. package/core/client/components/account/KEmailManager.vue +0 -128
  378. package/core/client/components/account/KPasswordManager.vue +0 -90
  379. package/core/client/components/account/KVerifyEmailManager.vue +0 -105
  380. package/core/client/components/collection/KColumn.vue +0 -227
  381. package/core/client/components/collection/KHistory.vue +0 -113
  382. package/core/client/components/collection/KHistoryEntry.vue +0 -109
  383. package/coverage/core/api/hooks/hooks.organisations.js.html +0 -541
  384. package/coverage/core/api/services/organisations/organisations.service.js.html +0 -343
  385. package/coverage/core/api/utils.js.html +0 -118
  386. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +0 -541
  387. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +0 -343
  388. package/coverage/lcov-report/core/api/utils.js.html +0 -118
  389. package/coverage/tmp/coverage-151166-1723543324307-0.json +0 -1
  390. package/coverage/tmp/coverage-151178-1723543324283-0.json +0 -1
  391. package/coverage/tmp/coverage-151189-1723543324271-0.json +0 -1
  392. package/coverage/tmp/coverage-151201-1723543324248-0.json +0 -1
  393. package/coverage/tmp/coverage-151208-1723543324227-0.json +0 -1
  394. package/scripts/kash/LICENSE +0 -21
  395. package/test/api/core/test-log-2024-04-22.log +0 -84
  396. package/test/api/core/test-log-2024-04-23.log +0 -23
  397. package/test/api/core/test-log-2024-08-13.log +0 -3
  398. package/test/api/map/test-log-2025-03-08.log +0 -0
@@ -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) {
@@ -1,15 +1,17 @@
1
+ import _ from 'lodash'
2
+ import { ForecastProbeId, updateTimeSeries } from '../utils/utils.time-series.js'
3
+ import { Layout } from '../../../core/client/layout.js'
4
+
1
5
  export const featureSelection = {
2
6
  watch: {
3
7
  'selection.items': {
4
8
  handler () {
5
- this.updateHighlights()
6
- this.handleWidget(this.getWidgetForSelection())
9
+ this.updateSelection()
7
10
  }
8
11
  },
9
12
  'probe.item': {
10
13
  handler () {
11
- this.updateHighlights()
12
- this.handleWidget(this.getWidgetForProbe())
14
+ this.updateSelection()
13
15
  }
14
16
  }
15
17
  },
@@ -19,11 +21,45 @@ export const featureSelection = {
19
21
  this.getSelectedItems().forEach(item => {
20
22
  this.highlight(item.feature || item.location, item.layer)
21
23
  })
22
- if (this.hasProbedLocation()) this.highlight(this.getProbedLocation(), this.getProbedLayer())
24
+ },
25
+ async updateProbedLocationHighlight () {
26
+ if (this.hasProbedLocation()) {
27
+ this.highlight(this.getProbedLocation(), this.getProbedLayer() || { name: ForecastProbeId })
28
+ }
29
+ },
30
+ async updateSelection () {
31
+ this.updateHighlights()
32
+ await this.updateTimeSeries()
33
+ // As probed location depends on time series do this after
34
+ await this.updateProbedLocationHighlight()
35
+ if (this.hasProbedLocation() || this.hasSelectedItems()) {
36
+ this.handleWidget(this.getWidgetForProbe() || this.getWidgetForSelection())
37
+ }
38
+ },
39
+ async updateTimeSeries () {
40
+ if (!this.state) return
41
+ const timeSeries = await updateTimeSeries(this.state.timeSeries || [])
42
+ this.state.timeSeries = timeSeries
23
43
  },
24
44
  handleWidget (widget) {
25
45
  // If window already open on another widget keep it
26
46
  if (widget && (widget !== 'none') && !this.isWidgetWindowVisible(widget)) this.openWidget(widget)
27
47
  }
48
+ },
49
+ mounted () {
50
+ this.$engineEvents.on('forecast-model-changed', this.updateSelection)
51
+ this.$engineEvents.on('selected-level-changed', this.updateSelection)
52
+ // We use debounce here to avoid multiple refresh when editing settings for instance
53
+ this.requestTimeSeriesUpdate = _.debounce(() => this.updateTimeSeries(), 250)
54
+ this.$events.on('timeseries-group-by-changed', this.requestTimeSeriesUpdate)
55
+ this.$events.on('units-changed', this.requestTimeSeriesUpdate)
56
+ this.$events.on('time-current-time-changed', this.updateProbedLocationHighlight)
57
+ },
58
+ beforeUnmount () {
59
+ this.$engineEvents.off('forecast-model-changed', this.updateSelection)
60
+ this.$engineEvents.off('selected-level-changed', this.updateSelection)
61
+ this.$events.off('timeseries-group-by-changed', this.updateTimeSeries)
62
+ this.$events.off('units-changed', this.requestTimeSeriesUpdate)
63
+ this.$events.off('time-current-time-changed', this.requestTimeSeriesUpdate)
28
64
  }
29
65
  }
@@ -24,7 +24,7 @@ export const Planets = {
24
24
 
25
25
  const client = await createClient(options)
26
26
  setupApi.bind(client)(options)
27
- client.on('authenticated', (data) => {
27
+ client.on('login', (data) => {
28
28
  // Store API gateway token if any
29
29
  if (data.gatewayToken) client.get('storage').setItem(options.gatewayJwt, data.gatewayToken)
30
30
  })
@@ -2,7 +2,7 @@ import logger from 'loglevel'
2
2
  import _ from 'lodash'
3
3
  import { kml } from '@tmcw/togeojson'
4
4
  import { i18n } from '../../../core/client/i18n.js'
5
- import { convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle } from '../utils/utils.style.js'
5
+ import { convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle, kmlStyleSpecialProperties } from '../utils/utils.style.js'
6
6
 
7
7
  export const KMLReader = {
8
8
  read (files, options) {
@@ -39,13 +39,12 @@ export const KMLReader = {
39
39
 
40
40
  function getExtraPropertiesFromKMLByName (document) {
41
41
  const properties = {}
42
- const propertiesToAdd = ['extrude', 'altitudeMode']
43
42
  const placemarks = document.getElementsByTagName('Placemark')
44
43
  _.forEach(placemarks, placemark => {
45
44
  const nameElements = placemark.getElementsByTagName('name')
46
45
  if (!nameElements.length) return
47
46
  const name = nameElements[0].textContent
48
- _.forEach(propertiesToAdd, property => {
47
+ _.forEach(kmlStyleSpecialProperties, property => {
49
48
  const propertyElements = placemark.getElementsByTagName(property)
50
49
  if (!propertyElements.length) return
51
50
 
@@ -2,6 +2,7 @@ import _ from 'lodash'
2
2
  import sift from 'sift'
3
3
  import { api, i18n, Store } from '../../../core/client/index.js'
4
4
  import { buildUrl } from '../../../core/common/index.js'
5
+ import { getCatalogProjectQuery, getViewsProjectQuery } from './utils.project.js'
5
6
 
6
7
  // Helper to set a JWT as query param in a target URL
7
8
  export function setUrlJwt (item, path, baseUrl, jwtField, jwt) {
@@ -104,17 +105,19 @@ export async function getLayers (options = {}) {
104
105
  context: '',
105
106
  planetApi: api
106
107
  })
107
-
108
+ // We expect the project object to expose the underlying API
109
+ const planetApi = (options.project && typeof options.project.getPlanetApi === 'function' ? options.project.getPlanetApi() : options.planetApi)
110
+
108
111
  let layers = []
109
- const catalogService = options.planetApi.getService('catalog', options.context)
112
+ const catalogService = planetApi.getService('catalog', options.context)
110
113
  if (catalogService) {
111
- const response = await catalogService.find({ query: options.query })
114
+ const response = await catalogService.find({ query: (options.project ? Object.assign(getCatalogProjectQuery(options.project), options.query) : options.query) })
112
115
  _.forEach(response.data, processTranslations)
113
116
  // Set which API to use to retrieve layer data
114
- layers = layers.concat(response.data.map(layer => Object.assign(layer, { getPlanetApi: () => options.planetApi })))
117
+ layers = layers.concat(response.data.map(layer => Object.assign(layer, { getPlanetApi: () => planetApi })))
115
118
  }
116
119
  // Do we need to inject a token ?
117
- await setEngineJwt(layers, options.planetApi)
120
+ await setEngineJwt(layers, planetApi)
118
121
  return layers
119
122
  }
120
123
 
@@ -124,9 +127,11 @@ export async function getCategories (options = {}) {
124
127
  context: '',
125
128
  planetApi: api
126
129
  })
130
+ // We expect the project object to expose the underlying API
131
+ const planetApi = (options.project && typeof options.project.getPlanetApi === 'function' ? options.project.getPlanetApi() : options.planetApi)
127
132
 
128
133
  let categories = []
129
- const catalogService = options.planetApi.getService('catalog', options.context)
134
+ const catalogService = planetApi.getService('catalog', options.context)
130
135
  if (catalogService) {
131
136
  const response = await catalogService.find({ query: Object.assign({ type: 'Category' }, options.query) })
132
137
  _.forEach(response.data, processTranslations)
@@ -141,9 +146,11 @@ export async function getSublegends (options = {}) {
141
146
  context: '',
142
147
  planetApi: api
143
148
  })
149
+ // We expect the project object to expose the underlying API
150
+ const planetApi = (options.project && typeof options.project.getPlanetApi === 'function' ? options.project.getPlanetApi() : options.planetApi)
144
151
 
145
152
  let sublegends = []
146
- const catalogService = options.planetApi.getService('catalog', options.context)
153
+ const catalogService = planetApi.getService('catalog', options.context)
147
154
  if (catalogService) {
148
155
  const response = await catalogService.find({ query: Object.assign({ type: 'Sublegend' }, options.query) })
149
156
  _.forEach(response.data, processTranslations)
@@ -173,13 +180,32 @@ export async function getViews (options = {}) {
173
180
  context: '',
174
181
  planetApi: api
175
182
  })
176
-
183
+ // We expect the project object to expose the underlying API
184
+ const planetApi = (options.project && typeof options.project.getPlanetApi === 'function' ? options.project.getPlanetApi() : options.planetApi)
185
+
177
186
  let views = []
178
- const catalogService = options.planetApi.getService('catalog', options.context)
187
+ const catalogService = planetApi.getService('catalog', options.context)
179
188
  if (catalogService) {
180
- const response = await catalogService.find({ query: Object.assign({ type: 'Context' }, options.query) })
189
+ const response = await catalogService.find({
190
+ query: Object.assign({ type: 'Context' }, (options.project ? Object.assign(getViewsProjectQuery(options.project), options.query) : options.query))
191
+ })
181
192
  _.forEach(response.data, processTranslations)
182
193
  views = views.concat(response.data)
183
194
  }
184
195
  return views
185
196
  }
197
+
198
+ // Order is given as an array of catalog item IDs or names
199
+ export function orderCatalogItemsBy(items, itemsOrder) {
200
+ if (!_.isEmpty(itemsOrder)) {
201
+ for (let i = itemsOrder.length; i >= 0; i--) {
202
+ const itemIdOrName = itemsOrder[i]
203
+ // Move item to beginning of array
204
+ const itemIndex = items.findIndex(item => (item?._id === itemIdOrName) || (item?.name === itemIdOrName))
205
+ if (itemIndex >= 0) {
206
+ const removedItems = items.splice(itemIndex, 1)
207
+ if (removedItems.length > 0) items.unshift(removedItems[0])
208
+ }
209
+ }
210
+ }
211
+ }
@@ -1,5 +1,6 @@
1
1
  import _ from 'lodash'
2
2
  import logger from 'loglevel'
3
+ import sift from 'sift'
3
4
  import { Notify, Loading, uid } from 'quasar'
4
5
  import explode from '@turf/explode'
5
6
  import SphericalMercator from '@mapbox/sphericalmercator'
@@ -366,8 +367,8 @@ async function generateStyleFromFilters (layer, defaultStyle) {
366
367
  const templates = generateStyleTemplates(defaultStyle, filters)
367
368
  const result = Object.assign(
368
369
  {},
369
- _.mapKeys(templates, (value, key) => `leaflet.${key}`),
370
- _.mapKeys(templates, (value, key) => `cesium.${key}`)
370
+ _.has(layer, 'leaflet') ? _.mapKeys(templates, (value, key) => `leaflet.${key}`) : {},
371
+ _.has(layer, 'cesium') ? _.mapKeys(templates, (value, key) => `cesium.${key}`) : {}
371
372
  )
372
373
  return result
373
374
  }
@@ -384,13 +385,18 @@ export async function editLayerStyle (layer, style, ignoreFeatureStyle = false)
384
385
  await api.getService('catalog').patch(layer._id, result)
385
386
  } else {
386
387
  const legend = await getLegendForLayer(Object.assign({}, layer, { 'cesium.style': style, 'leaflet.style': style }))
387
- const patch = Object.assign({}, { 'cesium.style': style, 'leaflet.style': style }, legend)
388
+ const patch = Object.assign(
389
+ {},
390
+ _.has(layer, 'cesium') ? { 'cesium.style': style } : {},
391
+ _.has(layer, 'leaflet') ? { 'leaflet.style': style } : {},
392
+ legend
393
+ )
388
394
  if (ignoreFeatureStyle) patch.ignoreFeatureStyle = true
389
395
  await api.getService('catalog').patch(layer._id, patch)
390
396
  }
391
397
  } else {
392
- _.set(layer, 'cesium.style', style)
393
- _.set(layer, 'leaflet.style', style)
398
+ if (_.has(layer, 'cesium')) _.set(layer, 'cesium.style', style)
399
+ if (_.has(layer, 'leaflet')) _.set(layer, 'leaflet.style', style)
394
400
  Object.assign(layer, await getLegendForLayer(layer))
395
401
  if (ignoreFeatureStyle) layer.ignoreFeatureStyle = true
396
402
  }
@@ -399,7 +405,7 @@ export async function editLayerStyle (layer, style, ignoreFeatureStyle = false)
399
405
 
400
406
  export async function updateLayerWithFiltersStyle (layer) {
401
407
  if (!layer._id) return
402
- const defaultStyle = getDefaultStyleFromTemplates(_.get(layer, 'leaflet.style', {}))
408
+ const defaultStyle = getDefaultStyleFromTemplates(_.get(layer, 'leaflet.style', _.get(layer, 'cesium.style', {})))
403
409
  const style = await generateStyleFromFilters(layer, defaultStyle)
404
410
  if (!style) return
405
411
 
@@ -408,7 +414,7 @@ export async function updateLayerWithFiltersStyle (layer) {
408
414
 
409
415
  export async function editFilterStyle (layer, filter, engineStyle, style, ignoreFeatureStyle = false) {
410
416
  if (!layer._id) return
411
- const layerDefaultStyle = getDefaultStyleFromTemplates(_.get(layer, 'leaflet.style', {}))
417
+ const layerDefaultStyle = getDefaultStyleFromTemplates(_.get(layer, 'leaflet.style', _.get(layer, 'cesium.style', {})))
412
418
 
413
419
  const filters = await parseFiltersFromLayer(layer)
414
420
  const targetFilterCondition = filterQueryToConditions(filter.active)
@@ -499,7 +505,7 @@ export async function getLegendForLayer (layer) {
499
505
  if (!hasFilterWithStyle) return { $unset: { legend: '' } }
500
506
  return legend
501
507
  } else {
502
- const layerStyle = getDefaultStyleFromTemplates(_.get(layer, 'leaflet.style', {}))
508
+ const layerStyle = getDefaultStyleFromTemplates(_.get(layer, 'leaflet.style', _.get(layer, 'cesium.style', {})))
503
509
  const legend = generateLegendFromStyle(layer, layerStyle, _.get(layer, 'geometryTypes', []))
504
510
  legend.label = _.get(layer, 'label', _.get(layer, 'name'))
505
511
  return { legend }
@@ -680,3 +686,28 @@ export async function removeLayer (layer) {
680
686
  Loading.hide()
681
687
  return true
682
688
  }
689
+
690
+ export function getFilterFunctionFromLayerFilters (layer) {
691
+ // To be flexible enough filters can provide a query for their active and inactive state
692
+ // Similarly, filters can be combined with a different operator for each state
693
+ const filterOperators = _.get(layer, 'filterOperators', { active: '$or', inactive: '$and' })
694
+ const activeFilters = layer.filters
695
+ .filter(filter => filter.isActive)
696
+ .map(filter => filter.active)
697
+ .filter(filter => !_.isEmpty(filter))
698
+ const activeCondition = activeFilters.length > 1
699
+ ? { [filterOperators.active]: activeFilters }
700
+ : activeFilters.length === 1 ? activeFilters[0] : {}
701
+ const inactiveFilters = layer.filters
702
+ .filter(filter => !filter.isActive)
703
+ .map(filter => filter.inactive)
704
+ .filter(filter => !_.isEmpty(filter))
705
+ const inactiveCondition = inactiveFilters.length > 1
706
+ ? { [filterOperators.inactive]: inactiveFilters }
707
+ : inactiveFilters.length === 1 ? inactiveFilters[0] : {}
708
+
709
+ const finalCondition = activeFilters.length && inactiveFilters.length
710
+ ? { '$and': [ activeCondition, inactiveCondition ] } : activeFilters.length ? activeCondition : inactiveCondition
711
+
712
+ return sift(finalCondition)
713
+ }
@@ -6,3 +6,7 @@ export function getCatalogProjectQuery (project) {
6
6
  const nameQuery = { name: { $in: _.map(_.filter(project.layers, 'name'), 'name') } }
7
7
  return { $or: [idQuery, nameQuery] }
8
8
  }
9
+
10
+ export function getViewsProjectQuery (project) {
11
+ return { _id: { $in: _.map(project.views, '_id') } }
12
+ }
@@ -182,6 +182,8 @@ export const DefaultStyle = {
182
182
  }
183
183
  }
184
184
 
185
+ export const kmlStyleSpecialProperties = ['extrude', 'altitudeMode']
186
+
185
187
  // Map properties of a given style according to given mapping, performing number conversion if required
186
188
  export function convertStyle (style, mapping, asNumber = []) {
187
189
  let convertedStyle = {}
@@ -328,12 +330,30 @@ export function generateStyleTemplates (defaultStyle, styles, dotify = true) {
328
330
 
329
331
  // Process all properties, for each property
330
332
  properties.forEach((property, index) => {
331
- if (!_.has(style.values, property)) return
332
- // Conversion from palette to RGB color is required
333
- const value = (property.includes('color')
334
- ? kdkCoreUtils.getHtmlColor(_.get(style.values, property))
335
- : _.get(style.values, property))
333
+ // Don't need to create template if the section (point, line, polygon) is not defined in the style
334
+ if (!_.get(style.values, property.split('.')[0])) return
335
+
336
+ let value = null
337
+ // If no value is defined for the given property, that means this property is in a optional sub-object (e.g. stroke, icon)
338
+ // So we need to hide the element corresponding to this sub-object by setting all of its properties to null or default values
339
+ // We must create the condition anyway to prevent default style from being applied on this case
340
+ if (!_.get(style.values, property)) {
341
+ if (_.isNumber(_.get(DefaultStyle, property))) {
342
+ value = 0
343
+ } else if (property.includes('shape')) {
344
+ value = _.get(DefaultStyle, property)
345
+ } else if (property.includes('color')) {
346
+ value = kdkCoreUtils.getHtmlColor(_.get(defaultStyle, property))
347
+ }
348
+ } else {
349
+ // Conversion from palette to RGB color is required
350
+ value = (property.includes('color')
351
+ ? kdkCoreUtils.getHtmlColor(_.get(style.values, property))
352
+ : _.get(style.values, property))
353
+ }
354
+
336
355
  // Generate style value for given property value
356
+ if (_.isNil(value)) return
337
357
  templates[index] += `if (${predicate}) { %>${value}<% } else `
338
358
  })
339
359
  })
@@ -346,18 +366,28 @@ export function generateStyleTemplates (defaultStyle, styles, dotify = true) {
346
366
  const value = (property.includes('color')
347
367
  ? kdkCoreUtils.getHtmlColor(_.get(defaultStyle, property))
348
368
  : _.get(defaultStyle, property))
369
+ if (_.isNil(value)) return
349
370
  // Avoid converting numbers to string on default values
350
371
  if (hasStyles) templates[index] += `{ %>${value}<% }`
351
372
  else templates[index] = value
352
373
  })
353
374
  // Set all templates
375
+ options.template = []
354
376
  properties.forEach((property, index) => {
355
- if (!_.has(defaultStyle, property)) return
377
+ if (!_.has(defaultStyle, property) || _.isEmpty(templates[index])) return
356
378
  // We voluntary use dot notation here by default as this object should be used to update style values using a patch operation
357
379
  if (dotify) options[`style.${property}`] = (hasStyles ? `<% ${templates[index]} %>` : templates[index])
358
380
  else _.set(options, `style.${property}`, (hasStyles ? `<% ${templates[index]} %>` : templates[index]))
381
+
382
+ // Check if templating is needed
383
+ if (options[`style.${property}`].startsWith('<% if')) {
384
+ options.template.push(`style.${property}`)
385
+ // Remove duplicates "<% { %>" that are added to default style (else statement) when filters are reapplied
386
+ options[`style.${property}`] = options[`style.${property}`].replace(/(<% { %>)+/g, '<% { %>').replace(/(<% } %>)+/g, '<% } %>')
387
+ } else {
388
+ options[`style.${property}`] = options[`style.${property}`].replace(/(<% { %>)+/g, '').replace(/(<% } %>)+/g, '')
389
+ }
359
390
  })
360
- options.template = (hasStyles ? properties : []).map(property => `style.${property}`)
361
391
  return options
362
392
  }
363
393