@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
@@ -6,14 +6,14 @@ export function useLayout () {
6
6
  function configureLayout (configuration, context) {
7
7
  if (_.has(configuration, 'view')) Layout.setView(configuration.view)
8
8
  if (_.has(configuration, 'padding')) Layout.setPadding(configuration.padding)
9
- if (_.has(configuration, 'header')) Layout.setHeader(configuration.header, context)
10
- if (_.has(configuration, 'footer')) Layout.setFooter(configuration.footer, context)
11
- if (_.has(configuration, 'page')) Layout.setPage(configuration.page, context)
12
- if (_.has(configuration, 'stickies')) Layout.setStickies(configuration.stickies, context)
13
- if (_.has(configuration, 'fab')) Layout.setFab(configuration.fab, context)
9
+ Layout.setHeader(configuration.header, context)
10
+ Layout.setFooter(configuration.footer, context)
11
+ Layout.setPage(configuration.page, context)
12
+ Layout.setStickies(configuration.stickies, context)
13
+ Layout.setFab(configuration.fab, context)
14
14
  Layout.placements.forEach(placement => {
15
- if (_.has(configuration, `panes.${placement}`)) Layout.setPane(placement, _.get(configuration, `panes.${placement}`), context)
16
- if (_.has(configuration, `windows.${placement}`)) Layout.setWindow(placement, _.get(configuration, `windows.${placement}`), context)
15
+ Layout.setPane(placement, _.get(configuration, `panes.${placement}`), context)
16
+ Layout.setWindow(placement, _.get(configuration, `windows.${placement}`), context)
17
17
  })
18
18
  // for backward compatibility
19
19
  if (_.has(configuration, 'leftPane')) Layout.setPane('left', configuration.leftPane, context)
@@ -41,7 +41,7 @@ export function useLayout () {
41
41
  function setLayoutMode (mode) {
42
42
  if (mode) Layout.setMode(mode)
43
43
  }
44
-
44
+
45
45
  // immediate
46
46
  const additionalFunctions = {}
47
47
  Layout.placements.forEach(placement => {
@@ -52,7 +52,7 @@ export function useLayout () {
52
52
  additionalFunctions[`set${_.upperFirst(placement)}PaneOpener`] = (opener) => { Layout.setPaneOpener(placement, opener) }
53
53
  additionalFunctions[`clear${_.upperFirst(placement)}Pane`] = () => { Layout.clearPane(placement) }
54
54
  })
55
-
55
+
56
56
  // expose
57
57
  return {
58
58
  Layout,
@@ -0,0 +1,50 @@
1
+ import _ from 'lodash'
2
+ import { api } from './api.js'
3
+
4
+ // Helper singleton to access configuration options stored in the database.
5
+ // Each configuration in an object like: { name, value }.
6
+ export const Configurations = {
7
+ initialize () {
8
+ if (!this.service) return
9
+ // We use a cache as the configuration is not updated often but can be read a lot of times
10
+ this.cache = {}
11
+ this.updateCache = (object) => {
12
+ if (object.name && this.cache[object.name]) this.cache[object.name] = object
13
+ }
14
+ this.service.on('patched', this.updateCache)
15
+ },
16
+ finalize () {
17
+ this.cache = {}
18
+ this.service.off('patched', this.updateCache)
19
+ },
20
+ getService () {
21
+ // Initialize on first use
22
+ if (!this.service) {
23
+ this.service = api.getService('configurations')
24
+ this.initialize()
25
+ }
26
+ return this.service
27
+ },
28
+ // Get a configuration object by its name
29
+ async get (name) {
30
+ const service = this.getService()
31
+ if (!service) return
32
+ // Update or return cache
33
+ if (this.cache[name]) return this.cache[name]
34
+ const response = await service.find({ query: { name } })
35
+ const object = _.get(response, 'data[0]')
36
+ if (object) this.cache[name] = object
37
+ return object
38
+ },
39
+ // Get the value associated to a configuration object by its name
40
+ async getValue (name, defaultValue = {}) {
41
+ const object = await this.get(name)
42
+ return _.get(object, 'value', defaultValue)
43
+ },
44
+ // Update the value associated to a configuration object by its name
45
+ async update (name, value) {
46
+ const object = await this.get(name)
47
+ if (!object || !object._id) return
48
+ await this.getService().patch(object._id, { value })
49
+ }
50
+ }
@@ -32,7 +32,7 @@ const ExporterQueue = {
32
32
  filename = `${_.get(request, 'basename', request.service)}_${timestamp}.${request.format}`
33
33
  }
34
34
  // retrieve the target service path
35
- let servicePath = api.getServicePath(request.service)
35
+ let servicePath = api.getServicePath(request.service, request.context)
36
36
  if (servicePath.startsWith('/')) servicePath = servicePath.substring(1)
37
37
  // retrieve the transform assigned to the format
38
38
  const transform = _.get(request, 'transform.' + request.format)
@@ -76,6 +76,10 @@
76
76
  "WEAK_PASSWORD_ONEOF": "Not known as one of the most common passwords",
77
77
  "WEAK_PASSWORD_PREVIOUS": "Not one of your {history} last passwords",
78
78
  "CANNOT_PROCESS_DOWNLOAD_DATA": "Invalid or incomplete data file",
79
+ "CANNOT_REMOVE_USER": "Your are not allowed to remove this accound.<br>Please remove the organisations owned by <b>{user}</b> first.",
80
+ "CANNOT_REMOVE_ORGANISATION": "You are not allowed to remove this organisation.<br>Please remove all the groups first.",
81
+ "CANNOT_REMOVE_LAST_OWNER": "You are not allowed to remove the last owner of <b>{resource}</b>",
82
+ "DUPLICATED_FILE": "The file {file} is already added",
79
83
  "OAUTH2_PROVIDER": "You cannot update your account because it is managed by {provider}, in order to switch to a local account reset your password first",
80
84
  "EMAIL_ALREADY_TAKEN": "A user with this email address seems to be already registered",
81
85
  "OBJECT_ID_ALREADY_TAKEN": "An item with this identifier seems to already exist. Please try again with another value.",
@@ -399,7 +403,8 @@
399
403
  "REGISTER_LABEL": "Register",
400
404
  "EMAIL_ALREADY_TAKEN": "Email already taken !",
401
405
  "REGISTER_ERROR": "Wrong input or service unavailable, please try again",
402
- "CONTEXTUAL_HELP": "@:NEED_HELP"
406
+ "CONTEXTUAL_HELP": "@:NEED_HELP",
407
+ "ALREADY_HAVE_AN_ACCOUNT_LINK": "Already have an account ?"
403
408
  },
404
409
  "KLogoutScreen": {
405
410
  "TITLE": "You are now logged out",
@@ -409,38 +414,6 @@
409
414
  "EDIT_PROFILE": "Edit my profile",
410
415
  "MANAGE_ACCOUNT": "Manage my account"
411
416
  },
412
- "KDeleteAccountManager": {
413
- "TITLE": "Delete my account",
414
- "QUESTION": "Are you sure you want to delete your account ?",
415
- "CONFIRMATION_TITLE": "Warning: the deletion of your account is irrevocable and all data attached to it will be lost",
416
- "CONFIRMATION": "Enter your account name to confirm the deletion"
417
- },
418
- "KPasswordManager": {
419
- "TITLE": "Change my password",
420
- "PASSWORD_CHANGED": "Your password has been successfully changed",
421
- "OLD_PASSWORD_FIELD_LABEL": "Enter your old password",
422
- "PASSWORD_FIELD_LABEL": "Enter your new password",
423
- "CONFIRM_PASSWORD_FIELD_LABEL": "Confirm your new password"
424
- },
425
- "KEmailManager": {
426
- "TITLE": "Change my email address",
427
- "PASSWORD_FIELD_LABEL": "Enter your password",
428
- "EMAIL_FIELD_LABEL": "Enter your new email address",
429
- "TOKEN_LABEL": "To validate your new email address, enter the code you received by email",
430
- "EMAIL_CHANGED": "You new address has been taken into account. An email has been sent to you to confirm the change.",
431
- "ERROR_MESSAGE": "Invalid code"
432
- },
433
- "KVerifyEmailManager": {
434
- "TITLE": "Check my email address",
435
- "HELP_LABEL": "Why should I verify my email address ?",
436
- "HELP_TEXT": "Verifying your email address improves the security of your account. Once you have verified your email address, both your password and access to your email account are required in order to make any changes to your account credentials, such as your password and contact email address. This helps further protect your account from being stolen by a potential phisher.",
437
- "HELP_EMAIL_LABEL": "I never received the verification email, what should I do ?",
438
- "HELP_EMAIL_TEXT": "If you do not receive your signup verification email and you are running a Spam filter, check and make sure the message has not been filtered as spam. Please try adding {email} to your contacts or trusted senders list within your email client and attempt to re-verify your email address. You can also click the button below and we'll send you the email again.",
439
- "TOKEN_LABEL": "Enter the code received by email to validate your email address",
440
- "EMAIL_VERIFIED": "Your address has been verified. An email has been sent to you to confirm the change.",
441
- "ACTION": "Resend verification code",
442
- "ERROR_MESSAGE": "Invalid code, request a new one"
443
- },
444
417
  "KSubscriptionsManager": {
445
418
  "TITLE": "Manage my subscriptions",
446
419
  "EMPTY": "No subscriptions"
@@ -471,12 +444,6 @@
471
444
  "KScrollToTop": {
472
445
  "TOOLTIP": "Scroll to top"
473
446
  },
474
- "KHistory": {
475
- "EMPTY_HISTORY": "@:NO_ITEM"
476
- },
477
- "KColumn": {
478
- "EMPTY_COLUMN": "@:NO_ITEM"
479
- },
480
447
  "KCard": {
481
448
  "MORE_DETAILS": "More details",
482
449
  "LESS_DETAILS": "Less details"
@@ -76,6 +76,10 @@
76
76
  "WEAK_PASSWORD_ONEOF": "Non reconnu comme l'un des mots de passe les plus courants",
77
77
  "WEAK_PASSWORD_PREVIOUS": "Différents de vos {history} derniers mots de passe",
78
78
  "CANNOT_PROCESS_DOWNLOAD_DATA": "Fichier invalide ou incomplet",
79
+ "CANNOT_REMOVE_USER": "Vous n’êtes pas autorisé à supprimer ce compte.<br>Veuillez d’abord supprimer les organisations appartenant à <b>{user}</b>.",
80
+ "CANNOT_REMOVE_ORGANISATION": "Vous n’êtes pas autorisé à supprimer cette organisation.<br>Veuillez d’abord supprimer tous les groupes.",
81
+ "CANNOT_REMOVE_LAST_OWNER": "Vous n’êtes pas autorisé à supprimer le dernier propriétaire de <b>{resource}</b>",
82
+ "DUPLICATED_FILE": "Le fichier {file} a déjà été ajouté",
79
83
  "OAUTH2_PROVIDER": "Vous ne pouvez modifier votre compte car il est géré par {provider}, pour utiliser un compte local réinitialisez tout d'abord votre mot de passe",
80
84
  "EMAIL_ALREADY_TAKEN": "Un utilisateur semble déjà enregistré avec cette adresse mail",
81
85
  "OBJECT_ID_ALREADY_TAKEN": "Un élément semble déjà enregistré avec cet identifiant. Merci de réessayer avec une autre valeur.",
@@ -399,7 +403,8 @@
399
403
  "REGISTER_LABEL": "S'enregistrer",
400
404
  "EMAIL_ALREADY_TAKEN": "Mail déjà utilisé !",
401
405
  "REGISTER_ERROR": "Mauvaise données ou service indisponible, veuillez réessayer",
402
- "CONTEXTUAL_HELP": "@:NEED_HELP"
406
+ "CONTEXTUAL_HELP": "@:NEED_HELP",
407
+ "ALREADY_HAVE_AN_ACCOUNT_LINK": "Déjà un compte ?"
403
408
  },
404
409
  "KLogoutScreen": {
405
410
  "TITLE": "Vous avez été déconnecté",
@@ -409,38 +414,6 @@
409
414
  "EDIT_PROFILE": "Éditer mon profil",
410
415
  "MANAGE_ACCOUNT": "Gérer mon compte"
411
416
  },
412
- "KDeleteAccountManager": {
413
- "TITLE": "Supprimer mon compte",
414
- "QUESTION": "Etes vous sûr de vouloir supprimer votre compte ?",
415
- "CONFIRMATION_TITLE": "Attention: la suppression de votre compte est irrévocable et toutes les données qui y sont attachées seront perdues",
416
- "CONFIRMATION": "Saisissez le nom de votre compte pour confirmer la surpression"
417
- },
418
- "KPasswordManager": {
419
- "TITLE": "Modifier mon mot de passe",
420
- "PASSWORD_CHANGED": "Votre mot de passe a été modifié avec succès",
421
- "OLD_PASSWORD_FIELD_LABEL": "Saisissez votre ancien mot de passe",
422
- "PASSWORD_FIELD_LABEL": "Saisissez votre nouveau mot de passe",
423
- "CONFIRM_PASSWORD_FIELD_LABEL": "Confirmez votre nouveau mot de passe"
424
- },
425
- "KEmailManager": {
426
- "TITLE": "Modifier mon adresse mail",
427
- "PASSWORD_FIELD_LABEL": "Saisissez votre mot de passe",
428
- "EMAIL_FIELD_LABEL": "Saisissez votre nouvelle adresse mail",
429
- "TOKEN_LABEL": "Pour valider votre nouvelle adresse mail, saisissez le code reçu par email",
430
- "EMAIL_CHANGED": "Votre nouvelle adresse a été prise en compte. Un mail vous a été envoyé pour confirmer le changement.",
431
- "ERROR_MESSAGE": "Code invalide"
432
- },
433
- "KVerifyEmailManager": {
434
- "TITLE": "Vérifier mon adresse mail",
435
- "HELP_LABEL": "Pourquoi dois-je vérifier mon adresse mail ?",
436
- "HELP_TEXT": "Vérifier votre adresse mail améliore la sécurité de votre compte. Une fois que votre adresse mail est validée, vous serez en mesure d'apporter des changements à votre compte tels que votre mot de passe. Cela permet de nous aider pour protéger votre compte contre d'éventuels actes de piraterie.",
437
- "HELP_EMAIL_LABEL": "Je n'ai jamais reçu de mail de vérification. Que dois-je faire ?",
438
- "HELP_EMAIL_TEXT": "Si vous n'avez pas reçu de mail de vérification, assurez-vous que le mail n'a pas été filtré et déplacé dans les spams de votre messagerie. Merci d'ajouter dans vos contacts l'adresse {email} dans votre client de messagerie. Vous pouvez également cliquer sur le bouton ci-dessous pour recevoir un nouveau mail de vérification.",
439
- "TOKEN_LABEL": "Saisissez le code reçu par email pour valider votre adresse mail",
440
- "EMAIL_VERIFIED": "Votre adresse a été vérifiée. Un mail vous a été envoyé pour confirmer le changement.",
441
- "ACTION": "Me renvoyer un code de vérification",
442
- "ERROR_MESSAGE": "Code invalide, demandez-en un nouveau"
443
- },
444
417
  "KSubscriptionsManager": {
445
418
  "TITLE": "Gérer mes souscriptions",
446
419
  "EMPTY": "Aucunes subscriptions"
@@ -471,12 +444,6 @@
471
444
  "KScrollToTop": {
472
445
  "TOOLTIP": "Haut de page"
473
446
  },
474
- "KHistory": {
475
- "EMPTY_HISTORY": "@:NO_ITEM"
476
- },
477
- "KColumn": {
478
- "EMPTY_COLUMN": "@:NO_ITEM"
479
- },
480
447
  "KCard": {
481
448
  "MORE_DETAILS": "Plus de détails",
482
449
  "LESS_DETAILS": "Moins de détails"
@@ -4,6 +4,7 @@ import config from 'config'
4
4
  import { Store } from './store.js'
5
5
  import { Theme } from './theme.js'
6
6
  import { Context } from './context.js'
7
+ import { Configurations } from './configurations.js'
7
8
  import { Platform } from './platform.js'
8
9
  import { Capabilities } from './capabilities.js'
9
10
  import { LocalStorage } from './local-storage.js'
@@ -33,6 +34,7 @@ import { Schema } from '../common/index.js'
33
34
  export { Store }
34
35
  export { Theme }
35
36
  export { Context }
37
+ export { Configurations }
36
38
  export { Platform }
37
39
  export { Capabilities }
38
40
  export { LocalStorage }
@@ -35,7 +35,7 @@ const defaults = {
35
35
  header: { ...contentDefaults, size: [undefined, 0] },
36
36
  footer: { ...contentDefaults, size: [undefined, 0] },
37
37
  page: { ...contentDefaults, size: [0, 0] },
38
- stickies: { ...contentDefaults, zIndex: DefaultZIndex.stickies },
38
+ stickies: { ...contentDefaults, zIndex: DefaultZIndex.stickies, expand: false },
39
39
  fab: { ...contentDefaults, icon: 'las la-ellipsis-v', position: 'bottom-right', offset: [16, 16], zIndex: DefaultZIndex.fab },
40
40
  panes: {
41
41
  left: { ...contentDefaults, ...paneDefaults, sizes: 300, zIndex: DefaultZIndex.drawer },
@@ -106,14 +106,14 @@ export const Layout = {
106
106
  set (layout) {
107
107
  if (_.has(layout, 'view')) this.setView(layout.view)
108
108
  if (_.has(layout, 'padding')) this.setPadding(layout.padding)
109
- if (_.has(layout, 'header')) this.setHeader(layout.header)
110
- if (_.has(layout, 'footer')) this.setFooter(layout.footer)
111
- if (_.has(layout, 'page')) this.setPage(layout.page)
112
- if (_.has(layout, 'stickies')) this.setStickies(layout.stickies)
113
- if (_.has(layout, 'fab')) this.setFab(layout.fab)
109
+ this.setHeader(layout.header)
110
+ this.setFooter(layout.footer)
111
+ this.setPage(layout.page)
112
+ this.setStickies(layout.stickies)
113
+ this.setFab(layout.fab)
114
114
  this.placements.forEach(placement => {
115
- if (_.has(layout, `panes.${placement}`)) this.setPane(placement, _.get(layout, `panes.${placement}`))
116
- if (_.has(layout, `windows.${placement}`)) this.setWindow(placement, _.get(layout, `windows.${placement}`))
115
+ this.setPane(placement, _.get(layout, `panes.${placement}`))
116
+ this.setWindow(placement, _.get(layout, `windows.${placement}`))
117
117
  })
118
118
  if (_.has(layout, 'mode')) this.setMode(layout.mode)
119
119
  if (_.has(layout, 'focus')) this.setFocus(layout.focus)
@@ -13,6 +13,9 @@ export function baseActivity (name) {
13
13
  configurePadding () {
14
14
  if (_.has(this.activityOptions, 'padding')) Layout.setPadding(_.get(this.activityOptions, 'padding'))
15
15
  },
16
+ setPadding (padding) {
17
+ Layout.setPadding(padding)
18
+ },
16
19
  clearPadding () {
17
20
  Layout.setPadding(true)
18
21
  },
@@ -92,7 +95,7 @@ export function baseActivity (name) {
92
95
  Layout.setPaneMode('bottom', mode)
93
96
  },
94
97
  setBottomPaneVisible (visible) {
95
- Layout.setPaneMode('bottom', visible)
98
+ Layout.setPaneVisible('bottom', visible)
96
99
  },
97
100
  configureBottomPane () {
98
101
  if (_.has(this.activityOptions, 'bottomPane')) Layout.setPane('bottom', _.get(this.activityOptions, 'bottomPane'), this)
@@ -116,7 +119,7 @@ export function baseActivity (name) {
116
119
  Layout.setPaneMode('right', mode)
117
120
  },
118
121
  setRightPaneVisible (visible) {
119
- Layout.setPaneMode('right', visible)
122
+ Layout.setPaneVisible('right', visible)
120
123
  },
121
124
  configureRightPane () {
122
125
  if (_.has(this.activityOptions, 'rightPane')) Layout.setPane('right', _.get(this.activityOptions, 'rightPane'), this)
@@ -53,6 +53,9 @@ export const baseField = {
53
53
  helperContext () {
54
54
  return _.get(this.properties.field.helper, 'context', null)
55
55
  },
56
+ hasFocus () {
57
+ return _.get(this.properties.field, 'focus', false)
58
+ },
56
59
  hasError () {
57
60
  return !_.isEmpty(this.error)
58
61
  },
@@ -117,9 +120,6 @@ export const baseField = {
117
120
  }
118
121
  // Tell the form that this field has a new value.
119
122
  // Consequently the form will validate or invalidate the field
120
- // Warning: This method must be called once the form is mounted
121
- // We need to force a refresh so that the model is correctly updated by Vuejs
122
- await this.$nextTick()
123
123
  this.$emit('field-changed', this.properties.name, this.model)
124
124
  },
125
125
  apply (object, field) {
@@ -1,5 +1,6 @@
1
1
  import _ from 'lodash'
2
2
  import { api } from './api.js'
3
+ import { getLocale } from './utils/utils.locale.js'
3
4
  import { getIconName, processIcon } from './utils/index.js'
4
5
 
5
6
  // Export singleton
@@ -13,7 +14,7 @@ export const Search = {
13
14
  // Retrieve the service using the service or name key
14
15
  const service = api.getService(serviceDescriptor.service, serviceDescriptor.context)
15
16
  // Build the query using given template if any
16
- const query = Object.assign({}, serviceDescriptor.baseQuery)
17
+ const query = Object.assign({ $locale: getLocale() }, serviceDescriptor.baseQuery)
17
18
  // Then add partial match
18
19
  // We don't use set by dot here because Mongo queries on nested fields
19
20
  // require the key to contain the path and not nested objects
@@ -5,27 +5,27 @@ export function getCollectionService (name, context) {
5
5
  return api.getService(name, context)
6
6
  }
7
7
 
8
- export async function listItems (service, fields, filter= {}, limit = 50) {
8
+ export async function listItems (service, fields, filter = {}, limit = 50) {
9
9
  return service.find({ query: _.merge({}, filter, { $limit: limit, $select: fields }) })
10
10
  }
11
11
 
12
12
  export async function getOldestItem (service, field = 'createdAt', filter = {}) {
13
- const response = await service.find({ query: _.merge({}, filter, { $sort: {[field]: 1 }, $limit: 1 }) })
13
+ const response = await service.find({ query: _.merge({}, filter, { $sort: { [field]: 1 }, $limit: 1, [field]: { $ne: null } }) })
14
14
  return _.get(response, 'data[0]')
15
15
  }
16
16
 
17
17
  export async function getOldestTime (service, field = 'createdAt', filter = {}) {
18
- const oldestItem = await getOldestItem (service, field, filter)
18
+ const oldestItem = await getOldestItem(service, field, filter)
19
19
  return _.get(oldestItem, field)
20
20
  }
21
21
 
22
22
  export async function getLatestItem (service, field = 'createdAt', filter = {}) {
23
- const response = await service.find({ query: _.merge({}, filter, { $sort: {[field]: -1 }, $limit: 1 }) })
23
+ const response = await service.find({ query: _.merge({}, filter, { $sort: { [field]: -1 }, $limit: 1 }) })
24
24
  return _.get(response, 'data[0]')
25
25
  }
26
26
 
27
27
  export async function getLatestTime (service, field = 'createdAt', filter = {}) {
28
- const latestItem = await getLatestItem (service, field, filter)
28
+ const latestItem = await getLatestItem(service, field, filter)
29
29
  return _.get(latestItem, field)
30
30
  }
31
31
 
@@ -37,9 +37,9 @@ export async function getDistinctValues (service, field, filter = {}) {
37
37
  }
38
38
 
39
39
  export async function searchText (service, text, caseSensitive = false, diacriticSensitive = false, filter = {}) {
40
- const query = _.merge({
41
- $text: {
42
- $search: text,
40
+ const query = _.merge({
41
+ $text: {
42
+ $search: text,
43
43
  $caseSensitive: caseSensitive,
44
44
  $diacriticSensitive: diacriticSensitive
45
45
  }
@@ -26,5 +26,9 @@ export const CardSectionProps = {
26
26
  dense: {
27
27
  type: Boolean,
28
28
  default: false
29
+ },
30
+ context: {
31
+ type: Object,
32
+ default: () => null
29
33
  }
30
34
  }
@@ -30,7 +30,7 @@ export async function subscribeToPushNotifications () {
30
30
  return
31
31
  }
32
32
  // Data
33
- const userService = api.service('api/users')
33
+ const usersService = api.service('api/users')
34
34
  const date = moment.utc().toISOString()
35
35
  const currentSubscription = await getPushSubscription()
36
36
  const user = Store.get('user')
@@ -44,7 +44,7 @@ export async function subscribeToPushNotifications () {
44
44
  if (subscription.endpoint === currentSubscription.endpoint) subscription.lastActivity = date
45
45
  return subscription
46
46
  })
47
- userService.patch(user._id, { subscriptions: subscriptions })
47
+ usersService.patch(user._id, { subscriptions: subscriptions })
48
48
  logger.debug(`[KDK] New connection with subscription endpoint: ${currentSubscription.endpoint}`)
49
49
  return
50
50
  }
@@ -57,6 +57,6 @@ export async function subscribeToPushNotifications () {
57
57
  subscription.lastActivity = date
58
58
  // Patch user subscriptions
59
59
  await addSubscription(user, subscription, 'subscriptions')
60
- userService.patch(user._id, { subscriptions: user.subscriptions })
60
+ usersService.patch(user._id, { subscriptions: user.subscriptions })
61
61
  logger.debug(`[KDK] New webpush subscription registered with endpoint: ${subscription.endpoint}`)
62
62
  }
@@ -11,13 +11,15 @@ async function authenticate(authentication) {
11
11
  let user = Store.get('user')
12
12
  if (user) return
13
13
  // Store latest authentication data for offline mode
14
- try {
15
- await LocalCache.setItem('authentication', authentication)
16
- } catch (error) {
17
- logger.error(error)
18
- }
14
+ await LocalCache.setItem('authentication', authentication)
19
15
  // Anonymous user or user account ?
16
+ const payload = _.get(authentication, 'authentication.payload')
17
+ const subjectId = payload && (payload.sub || payload.appId)
20
18
  user = authentication.user ? authentication.user : { name: i18n.t('composables.ANONYMOUS'), anonymous: true }
19
+ // If no user we also allow for a stateless token with permissions inside
20
+ if (!authentication.user && subjectId) {
21
+ Object.assign(user, { _id: subjectId }, payload)
22
+ }
21
23
  Store.set('user', user)
22
24
  await updateAbilities()
23
25
  }
@@ -37,22 +37,46 @@ export const Shapes = {
37
37
  triangle: {
38
38
  viewBox: [0, 0, 100, 100],
39
39
  content: '<polygon points="50 0, 100 100, 0 100" />',
40
- radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.125), height: Math.round(r * 2 * 1.025) } }
40
+ radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.125), height: Math.round(r * 2 * 1.025) } },
41
+ icon: {
42
+ translation: ['-50%', '-15%']
43
+ },
44
+ text: {
45
+ translation: ['-50%', '-15%']
46
+ }
41
47
  },
42
48
  'triangle-down': {
43
49
  viewBox: [0, 0, 100, 100],
44
50
  content: '<polygon points="0 0, 100 0, 50 100" />',
45
- radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.125), height: Math.round(r * 2 * 1.025) } }
51
+ radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.125), height: Math.round(r * 2 * 1.025) } },
52
+ icon: {
53
+ translation: ['-50%', '-85%']
54
+ },
55
+ text: {
56
+ translation: ['-50%', '-85%']
57
+ }
46
58
  },
47
59
  'triangle-left': {
48
60
  viewBox: [0, 0, 100, 100],
49
61
  content: '<polygon points="0 50, 100 0, 100 100" />',
50
- radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.025), height: Math.round(r * 2 * 1.125) } }
62
+ radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.025), height: Math.round(r * 2 * 1.125) } },
63
+ icon: {
64
+ translation: ['-15%', '-50%']
65
+ },
66
+ text: {
67
+ translation: ['-15%', '-50%']
68
+ }
51
69
  },
52
70
  'triangle-right': {
53
71
  viewBox: [0, 0, 100, 100],
54
72
  content: '<polygon points="0 0, 100 50, 0 100" />',
55
- radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.025), height: Math.round(r * 2 * 1.125) } }
73
+ radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.025), height: Math.round(r * 2 * 1.125) } },
74
+ icon: {
75
+ translation: ['-85%', '-50%']
76
+ },
77
+ text: {
78
+ translation: ['-85%', '-50%']
79
+ }
56
80
  },
57
81
  star: {
58
82
  viewBox: [0, 0, 48, 48],
@@ -217,10 +241,10 @@ export function createShape (options) {
217
241
  }
218
242
  }
219
243
  }
220
- // Render icon
244
+ // Render icon
221
245
  let iconTag = ''
222
246
  if (options.icon) {
223
- if (!_.isNil(options.icon.classes) || !_.isNil(options.icon.url)) {
247
+ if (!_.isNil(options.icon.classes) || !_.isNil(options.icon.url) || !_.isNil(options.icon.symbol)) {
224
248
  if (!_.isEmpty(options.icon.classes) || !_.isEmpty(options.icon.url)) {
225
249
  let specificStyle = ''
226
250
  if (options.icon.url) {
@@ -242,12 +266,19 @@ export function createShape (options) {
242
266
  const rotation = options.icon.rotation || _.get(shape, 'icon.rotation', 0)
243
267
  iconTag += `style="position: absolute; top: 50%; left: 50%; transform: translate(${translation[0]},${translation[1]}) rotate(${rotation}deg); opacity: ${opacity}; ${specificStyle}"`
244
268
  iconTag += '/>'
269
+ } else {
270
+ let iconSize = options.icon.size ? getSize(options.icon.size) : size
271
+ const color = getHtmlColor(options.icon.color, defaultColor)
272
+ const opacity = options.icon.opacity || 1
273
+ const translation = options.icon.translation || _.get(shape, 'icon.translation', ['-50%', '-50%'])
274
+ const rotation = options.icon.rotation || _.get(shape, 'icon.rotation', 0)
275
+ iconTag = `<svg width=${iconSize.width} height=${iconSize.height} style="position: absolute; top: 50%; left: 50%; transform: translate(${translation[0]},${translation[1]}) rotate(${rotation}deg); opacity: ${opacity}" fill="${color}"><use href="${options.icon.symbol}"></svg>`
245
276
  }
246
277
  } else {
247
278
  logger.warn(`[KDK] icon must contain either the 'classes' property or the 'url' property`)
248
279
  }
249
280
  }
250
- // Render text
281
+ // Render text
251
282
  let textTag = ''
252
283
  if (options.text) {
253
284
  if (!_.isNil(options.text.label)) {
@@ -7,30 +7,29 @@ export function getTimezoneLabel (timezone) {
7
7
  return `${timezone} (${offset})`
8
8
  }
9
9
 
10
- // Convert to local time with timezone offset
11
- // datetime must be expressed as an ISOString
12
- export function toLocalTimezone (datetime, timezone) {
13
- return timezone ? moment.tz(datetime, timezone) : moment(datetime).local()
10
+ /*
11
+ Round hours to expected interval, e.g. 6 hourly interval i.e. 00 || 06 || 12 || 18
12
+ @return {Number}
13
+ */
14
+ export function roundHours (hours, interval) {
15
+ return (Math.floor(hours / interval) * interval)
14
16
  }
15
17
 
16
- // Convert from moment date/time to quasar format in local time zone
17
- export function toQuasarDate (date, format) {
18
- return Time.convertToLocal(date).format(format)
18
+ /*
19
+ Round minutes to expected interval, e.g. 10 minutely interval i.e. 00 || 10 || 20 || 30
20
+ @return {Number}
21
+ */
22
+ export function roundMinutes (minutes, interval) {
23
+ return (Math.floor(minutes / interval) * interval)
19
24
  }
20
25
 
21
- export function toQuasarTime (time, format) {
22
- return Time.convertToLocal(time).format(format)
26
+ /*
27
+ Round hours to expected interval
28
+ @return {Date}
29
+ */
30
+ export function getNearestIntervalTime (datetime, interval) {
31
+ // Compute nearest run T0, always in the past
32
+ const h = (interval > 3600 ? roundHours(datetime.hours(), interval / 3600) : datetime.hours())
33
+ const m = (interval <= 3600 ? roundMinutes(datetime.minutes(), interval / 60) : 0)
34
+ return datetime.clone().hours(h).minutes(m).seconds(0).milliseconds(0)
23
35
  }
24
-
25
- // Convert from quasar format in local time zone to moment date/time
26
- export function fromQuasarDate (date, format) {
27
- return (Time.getFormatTimezone()
28
- ? moment.tz(date, format, Time.getFormatTimezone())
29
- : moment(date, format))
30
- }
31
-
32
- export function fromQuasarTime (time, format) {
33
- return (Time.getFormatTimezone()
34
- ? moment.tz(time, format, Time.getFormatTimezone())
35
- : moment(time, format))
36
- }
@@ -15,7 +15,7 @@
15
15
  }
16
16
  },
17
17
  "avatar": {
18
- "type": "object",
18
+ "type": ["object", "null"],
19
19
  "field": {
20
20
  "component": "form/KFileField",
21
21
  "label": "schemas.AVATAR_FIELD_LABEL",
@@ -23,7 +23,8 @@
23
23
  "maxFileSize": 524288,
24
24
  "readContent": false,
25
25
  "storage": {
26
- "path": "avatars/<%= _id %>"
26
+ "path": "avatars/<%= _id %>",
27
+ "context": "global"
27
28
  }
28
29
  }
29
30
  }