@kalisio/kdk 2.4.1 → 2.5.2

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 (638) hide show
  1. package/core/api/application.js +12 -12
  2. package/core/api/authentication.js +51 -7
  3. package/core/api/hooks/hooks.authentication.js +1 -59
  4. package/core/api/hooks/hooks.authorisations.js +9 -104
  5. package/core/api/hooks/hooks.model.js +4 -0
  6. package/core/api/hooks/hooks.push.js +18 -14
  7. package/core/api/hooks/hooks.users.js +0 -91
  8. package/core/api/hooks/index.js +0 -2
  9. package/core/api/services/account/account.service.js +1 -1
  10. package/core/api/services/authorisations/authorisations.service.js +28 -31
  11. package/core/api/services/index.js +42 -50
  12. package/core/api/services/messages/messages.hooks.js +4 -3
  13. package/core/api/services/users/users.hooks.js +4 -3
  14. package/core/api/services/users/users.service.js +5 -0
  15. package/core/client/api.js +182 -71
  16. package/core/client/broadcaster.js +20 -0
  17. package/core/client/capabilities.js +17 -7
  18. package/core/client/components/KActivity.vue +29 -34
  19. package/core/client/components/KAvatar.vue +0 -6
  20. package/core/client/components/KChip.vue +142 -39
  21. package/core/client/components/KContent.vue +13 -32
  22. package/core/client/components/KDialog.vue +29 -8
  23. package/core/client/components/KEditor.vue +120 -0
  24. package/core/client/components/KFollower.vue +75 -0
  25. package/core/client/components/KLogo.vue +2 -3
  26. package/core/client/components/KModal.vue +30 -10
  27. package/core/client/components/KSponsor.vue +1 -1
  28. package/core/client/components/KTextArea.vue +2 -5
  29. package/core/client/components/account/KDeleteAccountManager.vue +1 -1
  30. package/core/client/components/account/KProfile.vue +52 -14
  31. package/core/client/components/account/KSubscription.vue +19 -9
  32. package/core/client/components/account/KSubscriptionsManager.vue +10 -11
  33. package/core/client/components/action/KAction.vue +44 -24
  34. package/core/client/components/action/KBugReportAction.vue +4 -5
  35. package/core/client/components/action/KToggleStickyVisibility.vue +41 -0
  36. package/core/client/components/action/KToggleWidgetVisibility.vue +41 -0
  37. package/core/client/components/app/KPlatform.vue +122 -35
  38. package/core/client/components/app/KRequestProgressBar.vue +59 -0
  39. package/core/client/components/app/KSettings.vue +13 -2
  40. package/core/client/components/app/KTour.vue +2 -2
  41. package/core/client/components/chart/KTimeSeriesChart.vue +11 -3
  42. package/core/client/components/collection/KCard.vue +27 -33
  43. package/core/client/components/collection/KCardSection.vue +3 -23
  44. package/core/client/components/collection/KColumn.vue +0 -5
  45. package/core/client/components/collection/KDescriptionCardSection.vue +10 -5
  46. package/core/client/components/collection/KFilterView.vue +15 -0
  47. package/core/client/components/collection/KGrid.vue +4 -9
  48. package/core/client/components/collection/KHistory.vue +0 -5
  49. package/core/client/components/collection/KHistoryEntry.vue +0 -2
  50. package/core/client/components/collection/KItem.vue +1 -2
  51. package/core/client/components/collection/KSearchFilterControl.vue +139 -0
  52. package/core/client/components/collection/KTable.vue +1 -4
  53. package/core/client/components/collection/KTagsFilterControl.vue +70 -0
  54. package/core/client/components/collection/KTagsFilterView.vue +61 -0
  55. package/core/client/components/collection/KTimeFilterControl.vue +40 -0
  56. package/core/client/components/collection/KTimeFilterView.vue +106 -0
  57. package/core/client/components/collection/KTimeLine.vue +18 -11
  58. package/core/client/components/document/KBrowser.vue +283 -0
  59. package/core/client/components/document/KCsv.vue +52 -0
  60. package/core/client/components/document/KDocument.vue +19 -5
  61. package/core/client/components/document/KImage.vue +50 -19
  62. package/core/client/components/document/KMarkdown.vue +10 -2
  63. package/core/client/components/document/KUploader.vue +126 -0
  64. package/core/client/components/document/KVideo.vue +39 -0
  65. package/core/client/components/form/KDateField.vue +70 -0
  66. package/core/client/components/form/KDateTimeRangeField.vue +6 -17
  67. package/core/client/components/form/KDatetimeField.vue +6 -13
  68. package/core/client/components/form/KForm.vue +8 -8
  69. package/core/client/components/form/KOptionsField.vue +2 -0
  70. package/core/client/components/form/KResolutionField.vue +54 -52
  71. package/core/client/components/form/KSelectField.vue +27 -13
  72. package/core/client/components/form/KTextareaField.vue +23 -5
  73. package/core/client/components/graphics/KIcon.vue +64 -0
  74. package/core/client/components/index.js +1 -3
  75. package/core/client/components/input/KColorPicker.vue +70 -0
  76. package/core/client/components/input/KIconPicker.vue +188 -0
  77. package/core/client/components/input/KShapePicker.vue +81 -0
  78. package/core/client/components/input/index.js +7 -1
  79. package/core/client/components/layout/KFab.vue +1 -1
  80. package/core/client/components/layout/KLayout.vue +14 -2
  81. package/core/client/components/layout/KOpener.vue +9 -11
  82. package/core/client/components/layout/KPage.vue +31 -17
  83. package/core/client/components/layout/KWindow.vue +34 -18
  84. package/core/client/components/menu/KMenu.vue +52 -36
  85. package/core/client/components/menu/KSubMenu.vue +105 -0
  86. package/core/client/components/messages/KMessageCard.vue +207 -0
  87. package/core/client/components/messages/KMessageComposer.vue +199 -0
  88. package/core/client/components/messages/KMessagesTimeLine.vue +137 -0
  89. package/core/client/components/messages/index.js +7 -0
  90. package/core/client/components/screen/KErrorScreen.vue +2 -3
  91. package/core/client/components/screen/KLogoutScreen.vue +3 -1
  92. package/core/client/components/screen/KOAuthLoginScreen.vue +15 -0
  93. package/core/client/components/screen/KOAuthLogoutScreen.vue +33 -0
  94. package/core/client/components/screen/KUnauthorizedScreen.vue +16 -0
  95. package/core/client/components/time/KAbsoluteTimeRange.vue +7 -14
  96. package/core/client/components/time/KDate.vue +55 -28
  97. package/core/client/components/time/KDateTime.vue +93 -37
  98. package/core/client/components/time/KDateTimeRange.vue +197 -52
  99. package/core/client/components/time/KTime.vue +55 -27
  100. package/core/client/composables/activity.js +40 -30
  101. package/core/client/composables/{counter.js → collection-counter.js} +2 -4
  102. package/core/client/composables/collection-filter.js +111 -0
  103. package/core/client/composables/collection-timerange.js +56 -0
  104. package/core/client/composables/collection.js +13 -11
  105. package/core/client/composables/context.js +92 -0
  106. package/core/client/composables/errors.js +83 -0
  107. package/core/client/composables/index.js +5 -1
  108. package/core/client/composables/layout.js +14 -11
  109. package/core/client/composables/messages.js +4 -4
  110. package/core/client/composables/pwa.js +20 -27
  111. package/core/client/composables/schema.js +1 -1
  112. package/core/client/composables/screen.js +21 -9
  113. package/core/client/composables/selection.js +16 -4
  114. package/core/client/composables/session.js +13 -7
  115. package/core/client/composables/store.js +2 -1
  116. package/core/client/context.js +38 -0
  117. package/core/client/directives/v-hover.js +7 -4
  118. package/core/client/document.js +43 -15
  119. package/core/client/events.js +2 -2
  120. package/core/client/exporter.js +5 -4
  121. package/core/client/filter.js +1 -8
  122. package/core/client/guards.js +3 -3
  123. package/core/client/hooks/hooks.logger.js +1 -1
  124. package/core/client/hooks/hooks.offline.js +32 -0
  125. package/core/client/hooks/index.js +2 -1
  126. package/core/client/i18n/core_en.json +95 -268
  127. package/core/client/i18n/core_fr.json +181 -353
  128. package/core/client/index.js +22 -8
  129. package/core/client/layout.js +64 -25
  130. package/core/client/local-cache.js +67 -0
  131. package/core/client/local-storage.js +6 -2
  132. package/core/client/mixins/index.js +0 -1
  133. package/core/client/mixins/mixin.base-activity.js +22 -10
  134. package/core/client/mixins/mixin.base-editor.js +1 -1
  135. package/core/client/mixins/mixin.base-field.js +10 -1
  136. package/core/client/mixins/mixin.base-item.js +14 -11
  137. package/core/client/mixins/mixin.service.js +1 -5
  138. package/core/client/platform.js +44 -0
  139. package/core/client/readers/reader.blob.js +3 -3
  140. package/core/client/readers/reader.csv.js +2 -2
  141. package/core/client/readers/reader.json.js +2 -2
  142. package/core/client/services/index.js +7 -11
  143. package/core/client/storage.js +43 -8
  144. package/core/client/template-context.js +14 -14
  145. package/core/client/time.js +2 -2
  146. package/core/client/units.js +7 -4
  147. package/core/client/utils/index.js +7 -5
  148. package/core/client/utils/utils.collection.js +71 -0
  149. package/core/client/utils/utils.colors.js +29 -8
  150. package/core/client/utils/utils.content.js +14 -14
  151. package/core/client/utils/utils.files.js +17 -0
  152. package/core/client/utils/utils.items.js +4 -0
  153. package/core/client/utils/utils.math.js +18 -1
  154. package/core/client/utils/utils.push.js +22 -13
  155. package/core/client/utils/utils.screen.js +6 -2
  156. package/core/client/utils/utils.services.js +42 -0
  157. package/core/client/utils/utils.session.js +48 -12
  158. package/core/client/utils/utils.shapes.js +15 -11
  159. package/core/common/permissions.js +3 -108
  160. package/core/common/schemas/messages.update.json +16 -0
  161. package/core/common/schemas/settings.update.json +27 -8
  162. package/core/common/utils.js +2 -0
  163. package/core/common/utils.offline.js +38 -0
  164. package/coverage/core/api/application.js.html +296 -296
  165. package/coverage/core/api/authentication.js.html +206 -74
  166. package/coverage/core/api/db.js.html +61 -61
  167. package/coverage/core/api/hooks/hooks.authentication.js.html +15 -189
  168. package/coverage/core/api/hooks/hooks.authorisations.js.html +172 -460
  169. package/coverage/core/api/hooks/hooks.groups.js.html +1 -1
  170. package/coverage/core/api/hooks/hooks.logger.js.html +16 -16
  171. package/coverage/core/api/hooks/hooks.model.js.html +52 -52
  172. package/coverage/core/api/hooks/hooks.organisations.js.html +1 -1
  173. package/coverage/core/api/hooks/hooks.push.js.html +58 -46
  174. package/coverage/core/api/hooks/hooks.query.js.html +136 -136
  175. package/coverage/core/api/hooks/hooks.schemas.js.html +1 -1
  176. package/coverage/core/api/hooks/hooks.service.js.html +1 -1
  177. package/coverage/core/api/hooks/hooks.storage.js.html +1 -1
  178. package/coverage/core/api/hooks/hooks.users.js.html +55 -328
  179. package/coverage/core/api/hooks/index.html +58 -88
  180. package/coverage/core/api/hooks/index.js.html +4 -10
  181. package/coverage/core/api/index.html +39 -54
  182. package/coverage/core/api/index.js.html +1 -1
  183. package/coverage/core/api/marshall.js.html +1 -1
  184. package/coverage/core/api/models/groups.model.mongodb.js.html +1 -1
  185. package/coverage/core/api/models/index.html +13 -58
  186. package/coverage/core/api/models/messages.model.mongodb.js.html +35 -35
  187. package/coverage/core/api/models/organisations.model.mongodb.js.html +3 -3
  188. package/coverage/core/api/models/tags.model.mongodb.js.html +1 -1
  189. package/coverage/core/api/models/users.model.mongodb.js.html +1 -1
  190. package/coverage/core/api/services/account/account.hooks.js.html +1 -1
  191. package/coverage/core/api/services/account/account.service.js.html +67 -67
  192. package/coverage/core/api/services/account/index.html +16 -16
  193. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
  194. package/coverage/core/api/services/authorisations/authorisations.service.js.html +120 -117
  195. package/coverage/core/api/services/authorisations/index.html +15 -15
  196. package/coverage/core/api/services/databases/databases.hooks.js.html +82 -82
  197. package/coverage/core/api/services/databases/databases.service.js.html +20 -20
  198. package/coverage/core/api/services/databases/index.html +32 -32
  199. package/coverage/core/api/services/groups/groups.hooks.js.html +1 -1
  200. package/coverage/core/api/services/groups/index.html +1 -1
  201. package/coverage/core/api/services/import-export/import-export.hooks.js.html +1 -1
  202. package/coverage/core/api/services/import-export/import-export.service.js.html +1 -1
  203. package/coverage/core/api/services/import-export/index.html +1 -1
  204. package/coverage/core/api/services/index.html +21 -21
  205. package/coverage/core/api/services/index.js.html +118 -154
  206. package/coverage/core/api/services/mailer/index.html +1 -1
  207. package/coverage/core/api/services/mailer/mailer.hooks.js.html +1 -1
  208. package/coverage/core/api/services/mailer/mailer.service.js.html +1 -1
  209. package/coverage/core/api/services/messages/index.html +21 -21
  210. package/coverage/core/api/services/messages/messages.hooks.js.html +86 -86
  211. package/coverage/core/api/services/organisations/index.html +1 -1
  212. package/coverage/core/api/services/organisations/organisations.hooks.js.html +1 -1
  213. package/coverage/core/api/services/organisations/organisations.service.js.html +23 -23
  214. package/coverage/core/api/services/push/index.html +1 -1
  215. package/coverage/core/api/services/push/push.hooks.js.html +1 -1
  216. package/coverage/core/api/services/push/push.service.js.html +1 -1
  217. package/coverage/core/api/services/storage/index.html +5 -5
  218. package/coverage/core/api/services/storage/storage.hooks.js.html +1 -1
  219. package/coverage/core/api/services/storage/storage.service.js.html +27 -27
  220. package/coverage/core/api/services/tags/index.html +1 -1
  221. package/coverage/core/api/services/tags/tags.hooks.js.html +1 -1
  222. package/coverage/core/api/services/users/index.html +23 -8
  223. package/coverage/core/api/services/users/users.hooks.js.html +1 -1
  224. package/coverage/core/api/services/users/users.service.js.html +100 -0
  225. package/coverage/core/api/utils.js.html +1 -1
  226. package/coverage/core/common/errors.js.html +1 -1
  227. package/coverage/core/common/index.html +42 -27
  228. package/coverage/core/common/index.js.html +1 -1
  229. package/coverage/core/common/permissions.js.html +195 -510
  230. package/coverage/core/common/schema.js.html +1 -1
  231. package/coverage/core/common/utils.js.html +12 -6
  232. package/coverage/core/common/utils.offline.js.html +199 -0
  233. package/coverage/index.html +121 -166
  234. package/coverage/lcov-report/core/api/application.js.html +296 -296
  235. package/coverage/lcov-report/core/api/authentication.js.html +206 -74
  236. package/coverage/lcov-report/core/api/db.js.html +61 -61
  237. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +15 -189
  238. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +172 -460
  239. package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +1 -1
  240. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +16 -16
  241. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +52 -52
  242. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +1 -1
  243. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +58 -46
  244. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +136 -136
  245. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +1 -1
  246. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +1 -1
  247. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +1 -1
  248. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +55 -328
  249. package/coverage/lcov-report/core/api/hooks/index.html +58 -88
  250. package/coverage/lcov-report/core/api/hooks/index.js.html +4 -10
  251. package/coverage/lcov-report/core/api/index.html +39 -54
  252. package/coverage/lcov-report/core/api/index.js.html +1 -1
  253. package/coverage/lcov-report/core/api/marshall.js.html +1 -1
  254. package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +1 -1
  255. package/coverage/lcov-report/core/api/models/index.html +13 -58
  256. package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +35 -35
  257. package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +3 -3
  258. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +1 -1
  259. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +1 -1
  260. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +1 -1
  261. package/coverage/lcov-report/core/api/services/account/account.service.js.html +67 -67
  262. package/coverage/lcov-report/core/api/services/account/index.html +16 -16
  263. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
  264. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +120 -117
  265. package/coverage/lcov-report/core/api/services/authorisations/index.html +15 -15
  266. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +82 -82
  267. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +20 -20
  268. package/coverage/lcov-report/core/api/services/databases/index.html +32 -32
  269. package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +1 -1
  270. package/coverage/lcov-report/core/api/services/groups/index.html +1 -1
  271. package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +1 -1
  272. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +1 -1
  273. package/coverage/lcov-report/core/api/services/import-export/index.html +1 -1
  274. package/coverage/lcov-report/core/api/services/index.html +21 -21
  275. package/coverage/lcov-report/core/api/services/index.js.html +118 -154
  276. package/coverage/lcov-report/core/api/services/mailer/index.html +1 -1
  277. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +1 -1
  278. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +1 -1
  279. package/coverage/lcov-report/core/api/services/messages/index.html +21 -21
  280. package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +86 -86
  281. package/coverage/lcov-report/core/api/services/organisations/index.html +1 -1
  282. package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +1 -1
  283. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +23 -23
  284. package/coverage/lcov-report/core/api/services/push/index.html +1 -1
  285. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +1 -1
  286. package/coverage/lcov-report/core/api/services/push/push.service.js.html +1 -1
  287. package/coverage/lcov-report/core/api/services/storage/index.html +5 -5
  288. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +1 -1
  289. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +27 -27
  290. package/coverage/lcov-report/core/api/services/tags/index.html +1 -1
  291. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +1 -1
  292. package/coverage/lcov-report/core/api/services/users/index.html +23 -8
  293. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +1 -1
  294. package/coverage/lcov-report/core/api/services/users/users.service.js.html +100 -0
  295. package/coverage/lcov-report/core/api/utils.js.html +1 -1
  296. package/coverage/lcov-report/core/common/errors.js.html +1 -1
  297. package/coverage/lcov-report/core/common/index.html +42 -27
  298. package/coverage/lcov-report/core/common/index.js.html +1 -1
  299. package/coverage/lcov-report/core/common/permissions.js.html +195 -510
  300. package/coverage/lcov-report/core/common/schema.js.html +1 -1
  301. package/coverage/lcov-report/core/common/utils.js.html +12 -6
  302. package/coverage/lcov-report/core/common/utils.offline.js.html +199 -0
  303. package/coverage/lcov-report/index.html +121 -166
  304. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +33 -27
  305. package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +1 -1
  306. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +4 -4
  307. package/coverage/lcov-report/map/api/hooks/index.html +5 -5
  308. package/coverage/lcov-report/map/api/hooks/index.js.html +1 -1
  309. package/coverage/lcov-report/map/api/index.html +1 -1
  310. package/coverage/lcov-report/map/api/index.js.html +1 -1
  311. package/coverage/lcov-report/map/api/marshall.js.html +1 -1
  312. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +1 -1
  313. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +1 -1
  314. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +1 -1
  315. package/coverage/lcov-report/map/api/models/index.html +1 -1
  316. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +1 -1
  317. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +1 -1
  318. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +1 -1
  319. package/coverage/lcov-report/map/api/services/alerts/index.html +1 -1
  320. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +10 -7
  321. package/coverage/lcov-report/map/api/services/catalog/index.html +5 -5
  322. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1 -1
  323. package/coverage/lcov-report/map/api/services/daptiles/index.html +1 -1
  324. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +78 -9
  325. package/coverage/lcov-report/map/api/services/features/features.service.js.html +307 -4
  326. package/coverage/lcov-report/map/api/services/features/index.html +7 -7
  327. package/coverage/lcov-report/map/api/services/index.html +5 -5
  328. package/coverage/lcov-report/map/api/services/index.js.html +171 -42
  329. package/coverage/lcov-report/map/api/services/projects/index.html +1 -1
  330. package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +1 -1
  331. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +1 -1
  332. package/coverage/lcov-report/map/common/errors.js.html +1 -1
  333. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +8 -5
  334. package/coverage/lcov-report/map/common/grid.js.html +1 -1
  335. package/coverage/lcov-report/map/common/index.html +5 -5
  336. package/coverage/lcov-report/map/common/index.js.html +1 -1
  337. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +1 -1
  338. package/coverage/lcov-report/map/common/moment-utils.js.html +1 -1
  339. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +1 -1
  340. package/coverage/lcov-report/map/common/opendap-utils.js.html +1 -1
  341. package/coverage/lcov-report/map/common/permissions.js.html +1 -1
  342. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +1 -1
  343. package/coverage/lcov-report/map/common/tms-utils.js.html +1 -1
  344. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +1 -1
  345. package/coverage/lcov-report/map/common/wcs-utils.js.html +1 -1
  346. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +1 -1
  347. package/coverage/lcov-report/map/common/wfs-utils.js.html +1 -1
  348. package/coverage/lcov-report/map/common/wms-utils.js.html +1 -1
  349. package/coverage/lcov-report/map/common/wmts-utils.js.html +1 -1
  350. package/coverage/lcov.info +2314 -3167
  351. package/coverage/map/api/hooks/hooks.catalog.js.html +33 -27
  352. package/coverage/map/api/hooks/hooks.features.js.html +1 -1
  353. package/coverage/map/api/hooks/hooks.query.js.html +4 -4
  354. package/coverage/map/api/hooks/index.html +5 -5
  355. package/coverage/map/api/hooks/index.js.html +1 -1
  356. package/coverage/map/api/index.html +1 -1
  357. package/coverage/map/api/index.js.html +1 -1
  358. package/coverage/map/api/marshall.js.html +1 -1
  359. package/coverage/map/api/models/alerts.model.mongodb.js.html +1 -1
  360. package/coverage/map/api/models/catalog.model.mongodb.js.html +1 -1
  361. package/coverage/map/api/models/features.model.mongodb.js.html +1 -1
  362. package/coverage/map/api/models/index.html +1 -1
  363. package/coverage/map/api/models/projects.model.mongodb.js.html +1 -1
  364. package/coverage/map/api/services/alerts/alerts.hooks.js.html +1 -1
  365. package/coverage/map/api/services/alerts/alerts.service.js.html +1 -1
  366. package/coverage/map/api/services/alerts/index.html +1 -1
  367. package/coverage/map/api/services/catalog/catalog.hooks.js.html +10 -7
  368. package/coverage/map/api/services/catalog/index.html +5 -5
  369. package/coverage/map/api/services/daptiles/daptiles.service.js.html +1 -1
  370. package/coverage/map/api/services/daptiles/index.html +1 -1
  371. package/coverage/map/api/services/features/features.hooks.js.html +78 -9
  372. package/coverage/map/api/services/features/features.service.js.html +307 -4
  373. package/coverage/map/api/services/features/index.html +7 -7
  374. package/coverage/map/api/services/index.html +5 -5
  375. package/coverage/map/api/services/index.js.html +171 -42
  376. package/coverage/map/api/services/projects/index.html +1 -1
  377. package/coverage/map/api/services/projects/projects.hooks.js.html +1 -1
  378. package/coverage/map/common/dynamic-grid-source.js.html +1 -1
  379. package/coverage/map/common/errors.js.html +1 -1
  380. package/coverage/map/common/geotiff-grid-source.js.html +8 -5
  381. package/coverage/map/common/grid.js.html +1 -1
  382. package/coverage/map/common/index.html +5 -5
  383. package/coverage/map/common/index.js.html +1 -1
  384. package/coverage/map/common/meteo-model-grid-source.js.html +1 -1
  385. package/coverage/map/common/moment-utils.js.html +1 -1
  386. package/coverage/map/common/opendap-grid-source.js.html +1 -1
  387. package/coverage/map/common/opendap-utils.js.html +1 -1
  388. package/coverage/map/common/permissions.js.html +1 -1
  389. package/coverage/map/common/time-based-grid-source.js.html +1 -1
  390. package/coverage/map/common/tms-utils.js.html +1 -1
  391. package/coverage/map/common/wcs-grid-source.js.html +1 -1
  392. package/coverage/map/common/wcs-utils.js.html +1 -1
  393. package/coverage/map/common/weacast-grid-source.js.html +1 -1
  394. package/coverage/map/common/wfs-utils.js.html +1 -1
  395. package/coverage/map/common/wms-utils.js.html +1 -1
  396. package/coverage/map/common/wmts-utils.js.html +1 -1
  397. package/coverage/tmp/{coverage-280506-1731704745613-0.json → coverage-122123-1739872365211-0.json} +1 -1
  398. package/coverage/tmp/{coverage-280518-1731704745599-0.json → coverage-122135-1739872365196-0.json} +1 -1
  399. package/coverage/tmp/{coverage-280529-1731704745588-0.json → coverage-122146-1739872365184-0.json} +1 -1
  400. package/coverage/tmp/{coverage-280541-1731704745574-0.json → coverage-122158-1739872365169-0.json} +1 -1
  401. package/coverage/tmp/{coverage-280548-1731704745545-0.json → coverage-122165-1739872365141-0.json} +1 -1
  402. package/extras/configs/helpers.js +78 -0
  403. package/extras/configs/panes.left.js +118 -0
  404. package/extras/configs/panes.top.js +222 -0
  405. package/extras/configs/stickies.js +57 -0
  406. package/extras/configs/widgets.left.js +23 -0
  407. package/extras/configs/widgets.top.js +73 -0
  408. package/extras/css/core.variables.scss +8 -0
  409. package/extras/images/north.svg +3 -0
  410. package/extras/tours/map/side-nav.js +3 -3
  411. package/map/api/hooks/hooks.catalog.js +56 -23
  412. package/map/api/hooks/hooks.query.js +19 -24
  413. package/map/api/models/catalog.model.mongodb.js +16 -2
  414. package/{core/api/models/groups.model.mongodb.js → map/api/models/styles.model.mongodb.js} +2 -1
  415. package/map/api/services/catalog/catalog.hooks.js +13 -7
  416. package/map/api/services/features/features.hooks.js +28 -5
  417. package/map/api/services/features/features.service.js +101 -0
  418. package/map/api/services/index.js +125 -46
  419. package/map/api/services/styles/styles.hooks.js +37 -0
  420. package/map/client/cesium/utils/index.js +1 -0
  421. package/map/client/cesium/utils/utils.cesium.js +397 -0
  422. package/map/client/cesium/utils/utils.features.js +8 -0
  423. package/map/client/cesium/utils/utils.geojson.js +59 -0
  424. package/map/client/cesium/utils/utils.style.js +134 -17
  425. package/map/client/components/KEditLayerData.vue +17 -79
  426. package/map/client/components/KFeatureEditor.vue +2 -7
  427. package/map/client/components/KFeaturesChart.vue +2 -6
  428. package/map/client/components/KFeaturesFilterEditor.vue +300 -0
  429. package/map/client/components/KFeaturesFilterManager.vue +196 -0
  430. package/map/client/components/KFeaturesTable.vue +0 -5
  431. package/map/client/components/KFilterCondition.vue +303 -0
  432. package/map/client/components/KLayerEditionToolbar.vue +4 -3
  433. package/map/client/components/KLayerEditor.vue +451 -36
  434. package/map/client/components/KMeasureTool.vue +36 -9
  435. package/map/client/components/KProjectMenu.vue +14 -8
  436. package/map/client/components/catalog/KAddLayer.vue +0 -4
  437. package/map/client/components/catalog/KBaseLayersSelector.vue +42 -46
  438. package/map/client/components/catalog/KConnectLayer.vue +295 -291
  439. package/map/client/components/catalog/KCreateLayer.vue +141 -146
  440. package/map/client/components/catalog/KCreateOfflineView.vue +100 -0
  441. package/map/client/components/catalog/KCreateView.vue +2 -8
  442. package/map/client/components/catalog/KFilteredLayerItem.vue +72 -25
  443. package/map/client/components/catalog/KImportLayer.vue +121 -129
  444. package/map/client/components/catalog/KLayerItem.vue +44 -32
  445. package/map/client/components/catalog/KLayersPanel.vue +45 -17
  446. package/map/client/components/catalog/KLayersSelector.vue +51 -50
  447. package/map/client/components/catalog/KProjectManager.vue +4 -8
  448. package/map/client/components/catalog/KProjectSelector.vue +33 -2
  449. package/map/client/components/catalog/KProjectsPanel.vue +84 -106
  450. package/map/client/components/catalog/KSelectLayers.vue +56 -69
  451. package/map/client/components/catalog/KSelectViews.vue +56 -69
  452. package/map/client/components/catalog/KViewSelector.vue +32 -2
  453. package/map/client/components/catalog/KViewsPanel.vue +178 -110
  454. package/map/client/components/catalog/KWeatherLayersSelector.vue +77 -85
  455. package/map/client/components/form/KLocationField.vue +21 -2
  456. package/map/client/components/form/KOwsLayerField.vue +1 -1
  457. package/map/client/components/form/KOwsServiceField.vue +102 -63
  458. package/map/client/components/form/KSelectLayersField.vue +1 -1
  459. package/map/client/components/form/KSelectViewsField.vue +1 -1
  460. package/map/client/components/form/KTimezoneField.vue +0 -1
  461. package/map/client/components/legend/KLegend.vue +4 -4
  462. package/map/client/components/location/KLocationCardSection.vue +16 -0
  463. package/map/client/components/location/KLocationMap.vue +3 -2
  464. package/map/client/components/location/KLocationSearch.vue +46 -8
  465. package/map/client/components/location/KLocationTimeLineCard.vue +25 -3
  466. package/map/client/components/location/KLocationTip.vue +57 -10
  467. package/map/client/components/selection/KFeaturesSelection.vue +71 -0
  468. package/map/client/components/selection/KSelectedLayerFeatures.vue +343 -0
  469. package/map/client/components/stickies/KAttribution.vue +115 -0
  470. package/map/client/components/stickies/KLevelSlider.vue +114 -0
  471. package/map/client/components/stickies/KNorthArrow.vue +26 -0
  472. package/map/client/components/stickies/KPosition.vue +103 -0
  473. package/map/client/components/stickies/KTarget.vue +34 -0
  474. package/map/client/components/styles/KLayerStyleAction.vue +58 -0
  475. package/map/client/components/styles/KStyleEditor.vue +273 -0
  476. package/map/client/components/styles/KStyleEditorSection.vue +79 -0
  477. package/map/client/components/styles/KStyleManager.vue +183 -0
  478. package/map/client/components/styles/KStylePreview.vue +64 -0
  479. package/map/client/components/styles/KStylePreviewItem.vue +68 -0
  480. package/map/client/components/styles/KStylePropertiesGroup.vue +76 -0
  481. package/map/client/components/styles/KStyleProperty.vue +136 -0
  482. package/map/client/components/styles/KStyleTip.vue +118 -0
  483. package/map/client/components/tools/KGeolocateTool.vue +3 -2
  484. package/map/client/components/tools/KSearchTool.vue +34 -6
  485. package/map/client/components/widget/KMapillaryViewer.vue +1 -1
  486. package/map/client/components/widget/KStackableTimeSeries.vue +8 -5
  487. package/map/client/composables/activity.js +29 -43
  488. package/map/client/composables/catalog.js +1 -1
  489. package/map/client/composables/highlight.js +117 -57
  490. package/map/client/composables/location.js +33 -14
  491. package/map/client/composables/project.js +9 -10
  492. package/map/client/composables/selection.js +136 -23
  493. package/map/client/geocoder.js +104 -0
  494. package/map/client/geolocation.js +1 -1
  495. package/map/client/globe.js +3 -0
  496. package/map/client/hooks/hooks.offline.js +95 -0
  497. package/map/client/hooks/index.js +1 -0
  498. package/map/client/i18n/map_en.json +159 -94
  499. package/map/client/i18n/map_fr.json +187 -128
  500. package/map/client/index.js +3 -0
  501. package/map/client/init.js +44 -8
  502. package/map/client/leaflet/BoxSelection.js +2 -2
  503. package/map/client/leaflet/GradientPath.js +84 -4
  504. package/map/client/leaflet/WindBarb.js +323 -0
  505. package/map/client/leaflet/utils/index.js +1 -0
  506. package/map/client/leaflet/utils/utils.events.js +8 -3
  507. package/map/client/leaflet/utils/utils.geojson.js +222 -0
  508. package/map/client/leaflet/utils/utils.style.js +10 -9
  509. package/map/client/map.js +3 -0
  510. package/map/client/mixins/globe/mixin.base-globe.js +151 -19
  511. package/map/client/mixins/globe/mixin.geojson-layers.js +208 -86
  512. package/map/client/mixins/globe/mixin.popup.js +3 -2
  513. package/map/client/mixins/globe/mixin.style.js +3 -1
  514. package/map/client/mixins/globe/mixin.tooltip.js +3 -2
  515. package/map/client/mixins/map/index.js +1 -3
  516. package/map/client/mixins/map/mixin.base-map.js +267 -79
  517. package/map/client/mixins/map/mixin.canvas-layers.js +44 -10
  518. package/map/client/mixins/map/mixin.edit-layers.js +142 -57
  519. package/map/client/mixins/map/mixin.geojson-layers.js +127 -204
  520. package/map/client/mixins/map/mixin.pmtiles-layers.js +24 -11
  521. package/map/client/mixins/map/mixin.tiled-mesh-layers.js +1 -2
  522. package/map/client/mixins/map/mixin.tiled-wind-layers.js +2 -1
  523. package/map/client/mixins/mixin.activity.js +61 -41
  524. package/map/client/mixins/mixin.context.js +19 -14
  525. package/map/client/mixins/mixin.feature-selection.js +0 -1
  526. package/map/client/mixins/mixin.feature-service.js +41 -59
  527. package/map/client/mixins/mixin.weacast.js +1 -1
  528. package/map/client/navigator.js +38 -0
  529. package/map/client/pixi-utils.js +1 -1
  530. package/map/client/planets.js +1 -1
  531. package/map/client/readers/reader.kml.js +57 -1
  532. package/map/client/utils/index.js +1 -0
  533. package/map/client/utils/utils.capture.js +10 -7
  534. package/map/client/utils/utils.catalog.js +2 -2
  535. package/map/client/utils/utils.features.js +193 -39
  536. package/map/client/utils/utils.js +0 -21
  537. package/map/client/utils/utils.layers.js +381 -4
  538. package/map/client/utils/utils.location.js +39 -74
  539. package/map/client/utils/utils.offline.js +89 -0
  540. package/map/client/utils/utils.style.js +133 -80
  541. package/map/common/geotiff-grid-source.js +2 -1
  542. package/map/common/permissions.js +2 -0
  543. package/map/common/schemas/capture.create.json +4 -4
  544. package/map/common/schemas/catalog.update.json +18 -2
  545. package/map/common/schemas/projects.create.json +2 -2
  546. package/map/common/schemas/projects.update.json +2 -2
  547. package/map/common/tms-utils.js +5 -5
  548. package/map/common/wcs-grid-source.js +2 -2
  549. package/map/common/wcs-utils.js +8 -8
  550. package/map/common/wfs-utils.js +10 -10
  551. package/map/common/wms-utils.js +7 -7
  552. package/map/common/wmts-utils.js +6 -6
  553. package/package.json +7 -4
  554. package/test/api/core/account.test.js +0 -72
  555. package/test/api/core/authentication.test.js +184 -0
  556. package/test/api/core/config/default.cjs +1 -3
  557. package/test/api/core/index.test.js +77 -151
  558. package/test/api/core/offline.test.js +55 -0
  559. package/test/api/core/push.test.js +3 -3
  560. package/test/api/core/{test-log-2024-11-05.log → test-log-2025-05-26.log} +1 -9
  561. package/test/api/map/alerts.test.js +1 -1
  562. package/test/api/map/config/default.cjs +2 -1
  563. package/test/api/map/data/vigicrues.observations.Q.json +47042 -0
  564. package/test/api/map/index.test.js +113 -9
  565. package/test/api/map/style.test.js +62 -0
  566. package/test/api/map/{test-log-2024-10-28.log → test-log-2025-05-26.log} +4 -3
  567. package/test/client/core/layout.js +2 -2
  568. package/test/client/core/runner.js +1 -1
  569. package/test/client/core/utils.js +52 -0
  570. package/test/client/map/catalog.js +1 -0
  571. package/core/api/hooks/hooks.groups.js +0 -48
  572. package/core/api/hooks/hooks.organisations.js +0 -152
  573. package/core/api/models/organisations.model.mongodb.js +0 -3
  574. package/core/api/models/tags.model.mongodb.js +0 -10
  575. package/core/api/services/groups/groups.hooks.js +0 -31
  576. package/core/api/services/organisations/organisations.hooks.js +0 -31
  577. package/core/api/services/organisations/organisations.service.js +0 -86
  578. package/core/api/services/tags/tags.hooks.js +0 -31
  579. package/core/api/utils.js +0 -11
  580. package/core/client/components/KChipsPane.vue +0 -103
  581. package/core/client/components/document/index.js +0 -9
  582. package/core/client/components/team/KAddMember.vue +0 -378
  583. package/core/client/components/team/KAddTag.vue +0 -121
  584. package/core/client/components/team/KChangeRole.vue +0 -118
  585. package/core/client/components/team/KGroupCard.vue +0 -110
  586. package/core/client/components/team/KGroupsActivity.vue +0 -78
  587. package/core/client/components/team/KJoinGroup.vue +0 -132
  588. package/core/client/components/team/KMemberCard.vue +0 -328
  589. package/core/client/components/team/KMemberFilter.vue +0 -49
  590. package/core/client/components/team/KMembersActivity.vue +0 -136
  591. package/core/client/components/team/KOrganisationsActivity.vue +0 -51
  592. package/core/client/components/team/KTagCard.vue +0 -72
  593. package/core/client/components/team/KTagsActivity.vue +0 -73
  594. package/core/client/components/team/index.js +0 -9
  595. package/core/client/mixins/mixin.base-context.js +0 -54
  596. package/core/client/utils/utils.platform.js +0 -12
  597. package/core/common/schemas/groups.create.json +0 -28
  598. package/core/common/schemas/groups.update.json +0 -28
  599. package/core/common/schemas/organisations.create.json +0 -28
  600. package/core/common/schemas/organisations.update.json +0 -49
  601. package/core/common/schemas/tags.create.json +0 -35
  602. package/core/common/schemas/tags.update.json +0 -35
  603. package/map/client/components/KAttribution.vue +0 -108
  604. package/map/client/components/KFeaturesFilter.vue +0 -259
  605. package/map/client/components/KLayerStyleEditor.vue +0 -118
  606. package/map/client/components/KLayerStyleForm.vue +0 -740
  607. package/map/client/components/KLevelSlider.vue +0 -100
  608. package/map/client/components/KNorth.vue +0 -31
  609. package/map/client/components/KPositionIndicator.vue +0 -83
  610. package/map/client/components/catalog/KCreateProject.vue +0 -100
  611. package/map/client/mixins/map/mixin.forecast-layers.js +0 -81
  612. package/map/client/mixins/map/mixin.georaster-layers.js +0 -107
  613. package/test/api/core/team.test.js +0 -670
  614. package/test/api/core/test-log-2023-12-19.log +0 -7
  615. package/test/api/core/test-log-2024-01-04.log +0 -14
  616. package/test/api/core/test-log-2024-05-14.log +0 -6
  617. package/test/api/core/test-log-2024-06-06.log +0 -23
  618. package/test/api/core/test-log-2024-06-26.log +0 -25
  619. package/test/api/core/test-log-2024-06-28.log +0 -2
  620. package/test/api/core/test-log-2024-07-09.log +0 -0
  621. package/test/api/core/test-log-2024-08-13.log +0 -69
  622. package/test/api/core/test-log-2024-10-28.log +0 -53
  623. package/test/api/core/test-log-2024-11-15.log +0 -23
  624. package/test/api/core/test-log-2024-11-18.log +0 -0
  625. package/test/api/core/test-log-2024-12-03.log +0 -30
  626. package/test/api/map/test-log-2023-11-24.log +0 -121
  627. package/test/api/map/test-log-2023-12-12.log +0 -29
  628. package/test/api/map/test-log-2023-12-13.log +0 -5
  629. package/test/api/map/test-log-2024-01-04.log +0 -2
  630. package/test/api/map/test-log-2024-01-11.log +0 -1
  631. package/test/api/map/test-log-2024-01-25.log +0 -19
  632. package/test/api/map/test-log-2024-06-06.log +0 -39
  633. package/test/api/map/test-log-2024-08-13.log +0 -13
  634. package/test/api/map/test-log-2024-08-20.log +0 -55
  635. package/test/api/map/test-log-2024-09-09.log +0 -92
  636. /package/extras/{logos → images}/kalisio.png +0 -0
  637. /package/extras/{icons → images}/target.svg +0 -0
  638. /package/test/api/map/data/{vigicrues.observations.json → vigicrues.observations.H.json} +0 -0
@@ -2,6 +2,8 @@ import _ from 'lodash'
2
2
  import path from 'path'
3
3
  import makeDebug from 'debug'
4
4
  import { fileURLToPath } from 'url'
5
+ import mongodb from 'mongodb'
6
+ const { ObjectID } = mongodb
5
7
 
6
8
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
7
9
  const modelsPath = path.join(__dirname, '..', 'models')
@@ -9,17 +11,44 @@ const servicesPath = path.join(__dirname, '..', 'services')
9
11
 
10
12
  const debug = makeDebug('kdk:core:services')
11
13
 
12
- export function createTagService (options = {}) {
14
+ export function getServiceNameAndContext (servicePath) {
13
15
  const app = this
14
- return app.createService('tags', Object.assign({
15
- servicesPath,
16
- modelsPath
17
- }, options))
16
+ // Get name from service path without api prefix
17
+ let name = servicePath.replace(app.get('apiPath').substring(1) + '/', '')
18
+ // Then without context if any
19
+ const lastSlash = name.lastIndexOf('/')
20
+ const contextId = (lastSlash >= 0 ? name.substring(0, lastSlash) : '')
21
+ // Check if a string is a valid MongoDB Object ID.
22
+ // We don't use ObjectID.isValid as it returns true for any string that contains 12 characters: https://jira.mongodb.org/browse/NODE-4912.
23
+ // Regular expression that checks for hex value
24
+ const checkForHexRegExp = /^[0-9a-fA-F]{24}$/
25
+ if (contextId && (contextId.length === 24) && checkForHexRegExp.test(contextId)) {
26
+ name = name.replace(contextId + '/', '')
27
+ return { name, contextId }
28
+ } else {
29
+ return { name }
30
+ }
18
31
  }
19
32
 
20
- export function removeTagService (options = {}) {
33
+ export function decorateDistributedService (service) {
21
34
  const app = this
22
- return app.removeService(app.getService('tags', options.context))
35
+ // Remote service are registered according to their path, ie with API prefix (but without trailing /)
36
+ const remoteService = app.service(service.path)
37
+ const { name, contextId } = getServiceNameAndContext.call(app, service.path)
38
+ remoteService.name = name
39
+ remoteService.context = contextId
40
+ // As remote services have no context, from the internal point of view path = name
41
+ // Unfortunately this property is already set and used by feathers-distributed and should not be altered
42
+ // remoteService.path = name
43
+ remoteService.app = app
44
+ remoteService.getPath = function (withApiPrefix) {
45
+ const path = (contextId ? contextId + '/' + name : name)
46
+ return (withApiPrefix ? app.get('apiPath') + '/' + path : path)
47
+ }
48
+ remoteService.getContextId = function () {
49
+ return contextId
50
+ }
51
+ return remoteService
23
52
  }
24
53
 
25
54
  export function createStorageService (options = {}) {
@@ -64,48 +93,17 @@ export function removeDatabasesService (options = {}) {
64
93
  return app.removeService(app.getService('databases', options.context))
65
94
  }
66
95
 
67
- export async function createOrganisationService (options = {}) {
68
- const app = this
69
-
70
- // Create services to manage MongoDB databases, organisations, etc.
71
- await createDatabasesService.call(app)
72
- const orgsService = await app.createService('organisations', { modelsPath, servicesPath })
73
-
74
- // Replication management
75
- const usersService = app.getService('users')
76
- const authorisationsService = app.getService('authorisations')
77
- // Ensure permissions are correctly distributed when replicated
78
- usersService.on('patched', user => {
79
- // Patching profile should not trigger abilities update since
80
- // it is a perspective and permissions are not available in this case
81
- // Updating abilities in this case will result in loosing permissions for orgs/groups as none are available
82
- if (_.has(user, 'organisations') || _.has(user, 'groups')) authorisationsService.updateAbilities(user)
83
- })
84
- // Ensure org services are correctly distributed when replicated
85
- orgsService.on('created', organisation => {
86
- // Check if already done (initiator)
87
- const orgMembersService = app.getService('members', organisation)
88
- if (!orgMembersService) {
89
- // Jump from infos/stats to real DB object
90
- const db = app.db.client.db(organisation._id.toString())
91
- orgsService.createOrganisationServices(organisation, db)
92
- }
93
- })
94
- orgsService.on('removed', organisation => {
95
- // Check if already done (initiator)
96
- const orgMembersService = app.getService('members', organisation)
97
- if (!orgMembersService) return
98
- orgsService.removeOrganisationServices(organisation)
99
- })
100
- return orgsService
101
- }
102
-
103
96
  export default async function () {
104
97
  const app = this
105
98
 
106
99
  const authConfig = app.get('authentication')
107
100
  if (authConfig) {
108
- await app.createService('users', { modelsPath, servicesPath })
101
+ await app.createService('users', {
102
+ modelsPath,
103
+ servicesPath,
104
+ methods: ['create', 'get', 'find', 'update', 'patch', 'remove', 'logout'],
105
+ events: ['logout']
106
+ })
109
107
  debug('\'users\' service created')
110
108
  await app.createService('account', {
111
109
  servicesPath,
@@ -137,12 +135,6 @@ export default async function () {
137
135
  debug('\'messages\' service created')
138
136
  }
139
137
 
140
- const orgConfig = app.get('organisations')
141
- if (orgConfig) {
142
- await createOrganisationService.call(app)
143
- debug('\'organisations\' service created')
144
- }
145
-
146
138
  const mailerConfig = app.get('mailer')
147
139
  if (mailerConfig) {
148
140
  await app.createService('mailer', { servicesPath })
@@ -1,13 +1,14 @@
1
- import fuzzySearch from 'feathers-mongodb-fuzzy-search'
2
1
  import commonHooks from 'feathers-hooks-common'
3
- import { diacriticSearch } from '../../hooks/index.js'
2
+ import fuzzySearch from 'feathers-mongodb-fuzzy-search'
3
+ import { diacriticSearch, marshallComparisonQuery } from '../../hooks/index.js'
4
4
 
5
5
  export default {
6
6
  before: {
7
7
  all: [],
8
8
  find: [
9
9
  fuzzySearch({ fields: ['title', 'body', 'author'] }),
10
- diacriticSearch()
10
+ diacriticSearch(),
11
+ marshallComparisonQuery
11
12
  ],
12
13
  get: [],
13
14
  create: [commonHooks.setNow('createdAt')],
@@ -56,9 +56,10 @@ export default {
56
56
  ],
57
57
  find: [],
58
58
  get: [],
59
- create: [updateAbilities()],
60
- update: [],
61
- patch: [sendNewSubscriptionEmail],
59
+ create: [updateAbilities({ subjectAsItem: true })],
60
+ update: [updateAbilities({ subjectAsItem: true })],
61
+ // Fetch user in this case as we might only have partial data and miss permission properties
62
+ patch: [updateAbilities({ subjectAsItem: true, fetchSubject: true }), sendNewSubscriptionEmail],
62
63
  remove: []
63
64
  },
64
65
 
@@ -0,0 +1,5 @@
1
+ export default {
2
+ logout (user) {
3
+ this.emit('logout', user)
4
+ }
5
+ }
@@ -6,21 +6,42 @@ import jwtdecode from 'jwt-decode'
6
6
  import feathers from '@feathersjs/client'
7
7
  import { io } from 'socket.io-client'
8
8
  import reactive from 'feathers-reactive/dist/feathers-reactive.js'
9
+ import createOfflineService from '@kalisio/feathers-localforage'
9
10
  import configuration from 'config'
10
11
  import { permissions } from '../common/index.js'
11
12
  import { Store } from './store.js'
13
+ import { LocalCache } from './local-cache.js'
12
14
  import { Events } from './events.js'
15
+ import * as hooks from './hooks/index.js'
16
+ import { makeServiceSnapshot } from '../common/utils.js'
13
17
 
14
- // Setup log level
15
- if (_.get(configuration, 'logs.level')) {
16
- logger.setLevel(_.get(configuration, 'logs.level'), false)
17
- } else {
18
- logger.setLevel('info')
19
- }
18
+ // Disable default feathers behavior of re-authenticating on disconnect
19
+ feathers.authentication.AuthenticationClient.prototype.handleSocket = () => {}
20
20
 
21
- export function createClient (config) {
21
+ export async function createClient (config) {
22
+ // Setup log level
23
+ if (_.get(configuration, 'logs.level')) {
24
+ logger.setLevel(_.get(configuration, 'logs.level'), false)
25
+ } else {
26
+ logger.setLevel('info')
27
+ }
22
28
  // Initiate the client
23
29
  const api = feathers()
30
+ // Initialize connection state/listeners
31
+ api.isDisconnected = !navigator.onLine
32
+ addEventListener('online', () => {
33
+ api.isDisconnected = false
34
+ Events.emit('navigator-reconnected', api)
35
+ })
36
+ addEventListener('offline', () => {
37
+ api.isDisconnected = true
38
+ Events.emit('navigator-disconnected', api)
39
+ })
40
+ // This can force to use offline services it they exist even if connected
41
+ api.useLocalFirst = config.useLocalFirst
42
+ api.setLocalFirstEnabled = function (enabled) {
43
+ api.useLocalFirst = enabled
44
+ }
24
45
 
25
46
  // Matchers that can be added to customize route guards
26
47
  let matchers = []
@@ -55,87 +76,148 @@ export function createClient (config) {
55
76
  api.matcher = siftMatcher
56
77
 
57
78
  // This avoid managing the API path before each service name
58
- // If a context is not given it will be retrieved from the store if any and used for contextual services
59
79
  api.getServicePath = function (name, context, withApiPrefix = true) {
60
- const options = _.get(api.serviceOptions, name, {})
61
- let path
62
- // For non-contextual services path is always the name
63
- if (!options.context) {
64
- path = name
65
- } else {
80
+ // Defaults to global service path on "nil" context
81
+ let path = name
82
+ if (!_.isEmpty(context)) {
66
83
  // Context is given as string ID or object ?
67
84
  if (typeof context === 'string') {
68
- if (context) path = context + '/' + name
69
- // Force global context on empty string
70
- else path = name
71
- } else if (typeof context === 'object') {
72
- if (context && context._id) path = context._id + '/' + name
73
- // Force global context on empty object
74
- else path = name
75
- } else {
76
- // Otherwise test for current context as service is registered as contextual
77
- const context = Store.get('context')
78
- if (context) {
79
- path = api.getServicePath(name, context, false)
80
- } else {
81
- // Because it could also be registered as global with the same name fallback
82
- path = name
83
- }
85
+ // 'global' keyword is to get the global service
86
+ if (context !== 'global') path = context + '/' + name
87
+ } else if (context._id) {
88
+ path = context._id + '/' + name
84
89
  }
85
90
  }
86
-
87
91
  if (withApiPrefix) {
88
92
  path = config.apiPath + '/' + path
89
93
  }
94
+ // Take care that feathers strip slashes
95
+ if (path.startsWith('/')) path = path.substr(1)
90
96
  return path
91
97
  }
92
- api.getService = function (name, context) {
93
- const path = api.getServicePath(name, context)
94
- const service = api.service(path)
95
- if (!service) {
96
- throw new Error('Cannot retrieve service ' + name + ' for context ' + (typeof context === 'object' ? context._id : context))
98
+ // If no context is given the current from the store will be retrieved (if any)
99
+ // and the associated contextual service returned (if any)
100
+ api.getServiceInstance = function (name, context, options = {}) {
101
+ // Depending on the create option we don't directly use service() here
102
+ // as it will automatically create a new service wrapper even if it does not exist
103
+ let service
104
+ // If a context is given use it
105
+ if (!_.isEmpty(context)) {
106
+ const servicePath = api.getServicePath(name, context)
107
+ service = (options.create ? api.service(servicePath) : api.services[servicePath])
108
+ } else { // Otherwise check for a potential current context to be used
109
+ const currentContext = Store.get('context')
110
+ const contextualPath = api.getServicePath(name, currentContext)
111
+ const contextualService = api.services[contextualPath]
112
+ const globalPath = api.getServicePath(name)
113
+ const globalService = api.services[globalPath]
114
+ // If one of the service do exist use it, contextual one first
115
+ service = contextualService || globalService
116
+ // Otherwise as a fallback create a new global service as we don't really know if context should apply,
117
+ // if so the app should declare it upfront
118
+ if (!service && options.create) {
119
+ service = api.service(globalPath)
120
+ }
97
121
  }
98
- // Store the path on first call
99
- if (!service.path) service.path = path
100
122
  return service
101
123
  }
102
- // Used to register an existing backend service with its options
103
- api.declareService = function (name, options = {}) {
104
- if (!_.has(api.serviceOptions, name)) _.set(api.serviceOptions, name, options)
124
+ // Check if an online, ie "standard", version of a service is available
125
+ api.getOnlineService = function (name, context, options = {}) {
126
+ return api.getServiceInstance(name, context, Object.assign({ create: true }, options))
105
127
  }
106
- api.getServiceOptions = function (name) {
107
- return _.get(api.serviceOptions, name)
128
+ // Check if an offline version of a service is available
129
+ api.getOfflineService = function (name, context, options = {}) {
130
+ return api.getServiceInstance(`${name}-offline`, context, Object.assign({ create: false }, options))
131
+ }
132
+ api.getService = function (name, context, options = {}) {
133
+ let service
134
+ // When offline try to use offline service version if any
135
+ if (api.isDisconnected || api.useLocalFirst) {
136
+ service = api.getOfflineService(name, context, options)
137
+ // In local first mode we allow to use remote service if offline one doesn't exist
138
+ if (!service && !api.useLocalFirst) {
139
+ // Do not throw as a lot of components expect services to be available at initialization, eg
140
+ // api.getService('xxx').on('event', () => ...)
141
+ // In this case we simply warn and return the wrapper to the online service.
142
+ // However, it is up to the application to make sure of not using such components when offline
143
+ // throw new Error('Cannot retrieve offline service ' + name + ' for context ' + (typeof context === 'object' ? context._id : context))
144
+ logger.warn('[KDK] Cannot retrieve offline service ' + name + ' for context ' + (typeof context === 'object' ? context._id : context))
145
+ }
146
+ }
147
+ if (!service) {
148
+ service = api.getOnlineService(name, context, options)
149
+ if (!service) {
150
+ throw new Error('Cannot retrieve service ' + name + ' for context ' + (typeof context === 'object' ? context._id : context))
151
+ }
152
+ }
153
+ return service
108
154
  }
109
155
  // Used to create a frontend only service with its options
110
156
  api.createService = function (name, options = {}) {
111
- let servicePath = options.path || name
112
- let contextId
113
- if (options.context) {
114
- contextId = (typeof options.context === 'object' ? options.context._id : options.context)
115
- servicePath = contextId + '/' + servicePath
116
- }
117
- servicePath = config.apiPath + '/' + servicePath
118
- if (servicePath.startsWith('/')) servicePath = servicePath.substr(1)
119
- api.declareService(name, options)
157
+ const servicePath = api.getServicePath(name, options.context)
158
+ // Service object/constructor fucntion provided ?
120
159
  let service = options.service
121
160
  // If we get a function try to call it assuming it will return the service object
122
161
  if (typeof service === 'function') {
123
162
  service = service(name, api, options)
124
163
  }
125
- // Need to register services with custom methods
126
- if (options.methods) {
127
- api.use(servicePath, service || api.transporter.service(servicePath), {
128
- methods: options.methods
129
- })
130
- } else {
131
- api.use(servicePath, service)
132
- }
164
+ // Otherwise initialize a default wrapper
165
+ if (!service) service = api.transporter.service(servicePath)
166
+ // Register service up-front (required for custom methods)
167
+ api.use(servicePath, service, options)
133
168
  service = api.service(servicePath)
134
169
  if (options.hooks) service.hooks(options.hooks)
135
170
  if (options.context) service.context = options.context
171
+ service.path = servicePath
136
172
  return service
137
173
  }
138
- // Helper fonctions to access/alter config used at creation time
174
+ // Used to create a frontend only service to be used in offline mode
175
+ // based on an online service name, will snapshot service data by default
176
+ api.createOfflineService = async function (serviceName, options = {}) {
177
+ const offlineServiceName = `${serviceName}-offline`
178
+ let offlineService = api.getOfflineService(serviceName)
179
+
180
+ if (!offlineService) {
181
+ // Pass options not used internally for offline management as service options and store it along with service
182
+ const serviceOptions = _.omit(options, ['hooks', 'snapshot', 'clear', 'baseQuery', 'baseQueries', 'dataPath'])
183
+ const services = await LocalCache.getItem('services') || {}
184
+ _.set(services, serviceName, serviceOptions)
185
+ await LocalCache.setItem('services', services)
186
+ offlineService = api.createService(offlineServiceName, {
187
+ service: createOfflineService({
188
+ id: '_id',
189
+ name: 'offline_services',
190
+ storeName: serviceName,
191
+ multi: true,
192
+ storage: ['IndexedDB'],
193
+ // FIXME: this should not be hard-coded as it depends on the service
194
+ // For now we set it at the max value but if a component
195
+ // does not explicitly set the limit it will get a lot of data
196
+ paginate: { default: 5000, max: 5000 }
197
+ }),
198
+ // Set required default hooks
199
+ hooks: _.defaultsDeep(_.get(options, 'hooks'), {
200
+ before: {
201
+ all: [hooks.ensureSerializable, hooks.removeServerSideParameters],
202
+ create: [hooks.generateId]
203
+ }
204
+ }),
205
+ ...serviceOptions
206
+ })
207
+ }
208
+
209
+ if (_.get(options, 'snapshot', true)) {
210
+ const service = api.getOnlineService(serviceName)
211
+ await makeServiceSnapshot(service, Object.assign({ offlineService }, options))
212
+ }
213
+
214
+ return offlineService
215
+ }
216
+ api.removeService = function (name, context) {
217
+ const path = api.getServicePath(name, context)
218
+ api.unuse(path)
219
+ }
220
+ // Helper functions to access/alter config used at creation time
139
221
  api.getConfig = function (path) {
140
222
  return (path ? _.get(config, path) : config)
141
223
  }
@@ -171,9 +253,9 @@ export function createClient (config) {
171
253
  if (_.has(resource, 'abilities')) resource = undefined
172
254
 
173
255
  const abilities = (hasUser ? _.get(user, 'abilities') : Store.get('user.abilities'))
174
- logger.debug('Check for abilities ', operation, service, context, resource, abilities)
256
+ logger.debug('[KDK] Check for abilities ', operation, service, context, resource, abilities)
175
257
  if (!abilities) {
176
- logger.debug('Access denied without abilities')
258
+ logger.debug('[KDK] Access denied without abilities')
177
259
  return false
178
260
  }
179
261
  let result
@@ -183,7 +265,7 @@ export function createClient (config) {
183
265
  const path = api.getServicePath(service, context, false)
184
266
  result = permissions.hasServiceAbilities(abilities, path)
185
267
  if (!result) {
186
- logger.debug('Access to service path ' + path + ' denied')
268
+ logger.debug('[KDK] Access to service path ' + path + ' denied')
187
269
  return false
188
270
  } else if (operation === 'service') {
189
271
  // When we only check for service-level access return
@@ -195,9 +277,9 @@ export function createClient (config) {
195
277
  result = abilities.can(operation)
196
278
  }
197
279
  if (!result) {
198
- logger.debug('Access to resource denied')
280
+ logger.debug('[KDK] Access to resource denied')
199
281
  } else {
200
- logger.debug('Access to resource granted')
282
+ logger.debug('[KDK] Access to resource granted')
201
283
  }
202
284
  return result
203
285
  }
@@ -215,6 +297,21 @@ export function createClient (config) {
215
297
  api.configure(api.transporter)
216
298
  // Retrieve our specific errors on rate-limiting
217
299
  api.socket.on('rate-limit', (error) => Events.emit('error', error))
300
+ // Disable default socketio behavior of buffering messages when disconnected
301
+ // Also keep track of connection state with the server
302
+ api.socket.io.on('reconnect', async () => {
303
+ api.isDisconnected = false
304
+ api.socket.sendBuffer = []
305
+ // Re-authenticate on reconnect
306
+ await api.reAuthenticate(true)
307
+ Events.emit('websocket-reconnected', api)
308
+ logger.info('[KDK] Socket has been reconnected')
309
+ })
310
+ api.socket.io.on('reconnect_error', () => {
311
+ api.isDisconnected = true
312
+ Events.emit('websocket-disconnected', api)
313
+ logger.error(new Error('[KDK] Socket has been disconnected'))
314
+ })
218
315
  }
219
316
  api.configure(feathers.authentication({
220
317
  storage: window.localStorage,
@@ -243,8 +340,6 @@ export function createClient (config) {
243
340
  if (_.get(config, 'renewJwt', true)) {
244
341
  api.on('login', api.renewJwtOnExpiration)
245
342
  }
246
- // Object used to store configuration options for services
247
- api.serviceOptions = {}
248
343
  // Override Feathers configure that do not manage async operations,
249
344
  // here we also simply call the function given as parameter but await for it
250
345
  api.configure = async function (fn) {
@@ -255,16 +350,32 @@ export function createClient (config) {
255
350
  // Define domain in config if not forced
256
351
  if (!api.getConfig('domain')) api.setConfig('domain', window.location.origin)
257
352
 
353
+ // It appears that navigator.onLine is not reliable so that
354
+ // we perform an actual request to the domain in order to ensure we are online.
355
+ // We avoid CORS errors with a request to your own origin.
356
+ // We also add a random query parameter to prevent cached responses.
357
+ if (!api.isDisconnected) {
358
+ try {
359
+ const url = new URL(api.getConfig('domain'))
360
+ url.searchParams.set('random', Math.random().toFixed(18).substring(2, 18))
361
+ await window.fetch(url.toString(), { method: 'HEAD' })
362
+ } catch (error) {
363
+ api.isDisconnected = true
364
+ Events.emit('navigator-disconnected', api)
365
+ logger.warn(`[KDK] Cannot request target domain ${api.getConfig('domain')}, setting state to offline`, error)
366
+ }
367
+ }
368
+
258
369
  return api
259
370
  }
260
371
 
261
372
  // We don't create a default client based on app configuration here
262
373
  // as we don't know when the file will be imported first,
263
374
  // eg it might be imported before another one updating the config.
264
- // It is up to the application to instanciate the client when required.
375
+ // It is up to the application to instantiate the client when required.
265
376
  export let api
266
- export function initializeApi (fn) {
267
- api = createClient(configuration)
377
+ export async function initializeApi (fn) {
378
+ api = await createClient(configuration)
268
379
  if (fn) fn.call(api, configuration)
269
380
  return api
270
381
  }
@@ -0,0 +1,20 @@
1
+ import _ from 'lodash'
2
+ import logger from 'loglevel'
3
+ import config from 'config'
4
+
5
+ export const Broadcaster = {
6
+ initialize () {
7
+ this.channelName = _.get(config, 'appSlug', _.kebabCase(_.get(config, 'appName', 'kdk')))
8
+ this.channel = new BroadcastChannel(this.channelName)
9
+ logger.debug(`[KDK] Broadcaster initialized with channel '${this.channelName}'`)
10
+ },
11
+ getChannelName () {
12
+ return this.channelName
13
+ },
14
+ getChannel () {
15
+ return this.channel
16
+ },
17
+ post (message) {
18
+ this.channel.postMessage(message)
19
+ }
20
+ }
@@ -1,26 +1,36 @@
1
1
  import _ from 'lodash'
2
2
  import logger from 'loglevel'
3
3
  import config from 'config'
4
+ import { LocalCache } from './local-cache.js'
4
5
  import { api } from './api.js'
5
6
  import { Store } from './store.js'
6
7
 
7
8
  // Export singleton
8
9
  export const Capabilities = {
9
10
  async initialize () {
10
- const capabilities = await window.fetch(api.getConfig('domain') + _.get(config, 'apiPath') + '/capabilities')
11
- const content = await capabilities.json()
12
- logger.debug('[KDK] Fetched capabilities:', content)
13
- this.content = content
11
+ // If browser has detected an offline state then go for cached data
12
+ if (api.isDisconnected || api.useLocalFirst) {
13
+ this.content = await LocalCache.getItem('capabilities')
14
+ }
15
+ if (!this.content) {
16
+ // Otherwise try to fetch capabilities from server
17
+ const capabilities = await window.fetch(api.getConfig('domain') + _.get(config, 'apiPath') + '/capabilities')
18
+ this.content = await capabilities.json()
19
+ // Store latest capabilities data for offline mode
20
+ await LocalCache.setItem('capabilities', this.content)
21
+ }
22
+ logger.debug('[KDK] Capabilities initialized with content:', this.content)
23
+ if (!this.content) return
14
24
  // Backend might override some defaults in client config
15
- _.forOwn(_.pick(content, ['gateway']), (value, key) => {
25
+ _.forOwn(_.pick(this.content, ['gateway']), (value, key) => {
16
26
  api.setConfig(key, value)
17
27
  })
18
28
  // Used to ensure backward compatibility
19
- Store.set('capabilities.api', content)
29
+ Store.set('capabilities.api', this.content)
20
30
  Store.set('capabilities.client', _.pick(config, ['version', 'buildNumber']))
21
31
  },
22
32
  get (key, defaultValue) {
23
- if (!this.content) logger.error(new Error('Capabilities must be initialized first'))
33
+ if (!this.content) logger.error(new Error('[KDK] Capabilities must be initialized first'))
24
34
  else return _.get(this.content, key, defaultValue)
25
35
  }
26
36
  }