@kalisio/kdk 2.5.3 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (545) hide show
  1. package/.github/workflows/main.yaml +35 -6
  2. package/client.globe.js +8 -0
  3. package/client.js +8 -0
  4. package/client.map.js +8 -0
  5. package/core/api/hooks/hooks.push.js +3 -2
  6. package/core/api/hooks/hooks.tags.js +56 -0
  7. package/core/api/models/tags.model.mongodb.js +8 -0
  8. package/core/api/services/index.js +33 -2
  9. package/core/api/services/tags/tags.hooks.js +47 -0
  10. package/core/client/api.js +5 -5
  11. package/core/client/components/KActivity.vue +3 -2
  12. package/core/client/components/KChip.vue +2 -2
  13. package/core/client/components/KEditor.vue +3 -1
  14. package/core/client/components/KFollower.vue +4 -4
  15. package/core/client/components/KStore.vue +1 -1
  16. package/core/client/components/KTab.vue +20 -7
  17. package/core/client/components/account/KProfile.vue +9 -25
  18. package/core/client/components/action/KAction.vue +10 -10
  19. package/core/client/components/action/KToggleFullscreenAction.vue +2 -11
  20. package/core/client/components/app/KHome.vue +3 -2
  21. package/core/client/components/collection/KFilter.vue +5 -4
  22. package/core/client/components/collection/KGrid.vue +5 -1
  23. package/core/client/components/collection/KItemsFilter.vue +47 -0
  24. package/core/client/components/collection/KItemsSorter.vue +42 -0
  25. package/core/client/components/collection/KScrollDown.vue +2 -2
  26. package/core/client/components/collection/KSearchFilterControl.vue +3 -2
  27. package/core/client/components/collection/KSorter.vue +33 -37
  28. package/core/client/components/collection/KTagsFilterControl.vue +14 -40
  29. package/core/client/components/collection/KTagsFilterView.vue +10 -45
  30. package/core/client/components/collection/KTimeFilterControl.vue +6 -7
  31. package/core/client/components/collection/KTimeFilterView.vue +13 -22
  32. package/core/client/components/collection/KTimeLine.vue +18 -9
  33. package/core/client/components/form/KColorField.vue +13 -6
  34. package/core/client/components/form/KColorScaleField.vue +7 -12
  35. package/core/client/components/form/KFileField.vue +118 -89
  36. package/core/client/components/form/KForm.vue +30 -18
  37. package/core/client/components/form/KIconField.vue +4 -1
  38. package/core/client/components/form/KNumberField.vue +9 -2
  39. package/core/client/components/form/KSelectField.vue +1 -4
  40. package/core/client/components/form/KTagField.vue +229 -0
  41. package/core/client/components/form/KTextField.vue +4 -0
  42. package/core/client/components/form/KTextareaField.vue +3 -1
  43. package/core/client/components/input/KShapePicker.vue +3 -3
  44. package/core/client/components/layout/KFab.vue +32 -20
  45. package/core/client/components/layout/KPage.vue +11 -6
  46. package/core/client/components/layout/KWindow.vue +5 -0
  47. package/core/client/components/media/index.js +2 -6
  48. package/core/client/components/menu/KMenu.vue +12 -10
  49. package/core/client/components/menu/KSubMenu.vue +12 -12
  50. package/core/client/components/messages/KMessageCard.vue +13 -12
  51. package/core/client/components/messages/KMessageComposer.vue +13 -9
  52. package/core/client/components/messages/KMessagesTimeLine.vue +16 -8
  53. package/core/client/components/tags/KTagFilter.vue +99 -0
  54. package/core/client/components/tags/KTagItem.vue +65 -0
  55. package/core/client/components/tags/KTagManager.vue +198 -0
  56. package/core/client/components/tags/KTagSelection.vue +82 -0
  57. package/core/client/components/time/KDate.vue +3 -17
  58. package/core/client/components/time/KDateTime.vue +1 -1
  59. package/core/client/components/time/KTime.vue +0 -4
  60. package/core/client/composables/collection-filter.js +41 -2
  61. package/core/client/composables/collection.js +3 -3
  62. package/core/client/composables/index.js +1 -0
  63. package/core/client/composables/pwa.js +13 -0
  64. package/core/client/composables/session.js +7 -8
  65. package/core/client/composables/user.js +36 -0
  66. package/core/client/directives/index.js +1 -0
  67. package/core/client/directives/v-drop-file.js +174 -0
  68. package/core/client/document.js +2 -1
  69. package/core/client/exporter.js +17 -3
  70. package/core/client/i18n/core_en.json +34 -7
  71. package/core/client/i18n/core_fr.json +36 -9
  72. package/core/client/i18n.js +26 -11
  73. package/core/client/layout.js +5 -5
  74. package/core/client/mixins/mixin.base-activity.js +8 -5
  75. package/core/client/mixins/mixin.base-editor.js +2 -1
  76. package/core/client/mixins/mixin.base-field.js +3 -2
  77. package/core/client/mixins/mixin.base-item.js +12 -10
  78. package/core/client/mixins/mixin.service.js +3 -1
  79. package/core/client/platform.js +0 -3
  80. package/core/client/readers/reader.json.js +2 -2
  81. package/core/client/utils/index.js +2 -0
  82. package/core/client/utils/utils.collection.js +6 -6
  83. package/core/client/utils/utils.colors.js +46 -19
  84. package/core/client/utils/utils.files.js +19 -0
  85. package/core/client/utils/utils.locale.js +13 -17
  86. package/core/client/utils/utils.services.js +27 -0
  87. package/core/client/utils/utils.shapes.js +2 -2
  88. package/core/client/utils/utils.tags.js +17 -0
  89. package/core/client/utils/utils.tours.js +31 -0
  90. package/core/common/permissions.js +3 -0
  91. package/core/common/schemas/tags.update.json +35 -0
  92. package/core/common/schemas/users.update-profile.json +1 -1
  93. package/core/common/utils.js +5 -5
  94. package/extras/configs/panes.top.js +11 -0
  95. package/extras/configs/stickies.js +1 -1
  96. package/extras/configs/widgets.left.js +13 -1
  97. package/extras/libs/jsts.min.js +8 -0
  98. package/{test/client/core/account.js → extras/tests/core/account.mjs} +4 -4
  99. package/extras/tests/core/api.mjs +114 -0
  100. package/{test/client/core/collection.js → extras/tests/core/collection.mjs} +8 -8
  101. package/{test/client/core/dialogs.js → extras/tests/core/dialogs.mjs} +1 -1
  102. package/extras/tests/core/index.mjs +9 -0
  103. package/{test/client/core/layout.js → extras/tests/core/layout.mjs} +7 -3
  104. package/{test/client/core/runner.js → extras/tests/core/runner.mjs} +3 -3
  105. package/{test/client/core/screens.js → extras/tests/core/screens.mjs} +1 -1
  106. package/{test/client/core/utils.js → extras/tests/core/utils.mjs} +79 -26
  107. package/extras/tests/index.mjs +4 -0
  108. package/{test/client/map/api.js → extras/tests/map/api.mjs} +1 -1
  109. package/{test/client/map/catalog.js → extras/tests/map/catalog.mjs} +18 -18
  110. package/{test/client/map/controls.js → extras/tests/map/controls.mjs} +3 -3
  111. package/extras/tests/map/index.mjs +5 -0
  112. package/{test/client/map/time.js → extras/tests/map/time.mjs} +3 -3
  113. package/{test/client/map/utils.js → extras/tests/map/utils.mjs} +6 -5
  114. package/extras/tours/fab.js +36 -0
  115. package/extras/tours/layout.js +49 -0
  116. package/extras/tours/pane.left.js +78 -0
  117. package/extras/tours/pane.right.js +145 -0
  118. package/extras/tours/pane.top.js +239 -0
  119. package/map/api/config/layers.cjs +28 -13
  120. package/map/api/hooks/hooks.query.js +12 -7
  121. package/map/api/models/catalog.model.mongodb.js +17 -6
  122. package/map/api/services/catalog/catalog.hooks.js +1 -1
  123. package/map/api/services/index.js +18 -1
  124. package/map/client/cesium/utils/utils.cesium.js +25 -65
  125. package/map/client/cesium/utils/utils.features.js +1 -0
  126. package/map/client/cesium/utils/utils.geojson.js +1 -0
  127. package/map/client/cesium/utils/utils.style.js +7 -6
  128. package/map/client/components/KFeatureEditor.vue +3 -3
  129. package/map/client/components/KFeaturesChart.vue +4 -4
  130. package/map/client/components/KFeaturesFilterEditor.vue +19 -13
  131. package/map/client/components/KFeaturesFilterManager.vue +7 -4
  132. package/map/client/components/KFeaturesTable.vue +2 -2
  133. package/map/client/components/KLayerEditor.vue +6 -6
  134. package/map/client/components/KMeasureTool.vue +2 -1
  135. package/map/client/components/catalog/KBaseLayersSelector.vue +1 -1
  136. package/map/client/components/catalog/KCategoryItem.vue +15 -1
  137. package/map/client/components/catalog/KConnectLayer.vue +2 -2
  138. package/map/client/components/catalog/KCreateView.vue +3 -2
  139. package/map/client/components/catalog/KFilteredLayerItem.vue +26 -6
  140. package/map/client/components/catalog/KImportLayer.vue +6 -3
  141. package/map/client/components/catalog/KLayerCategories.vue +6 -6
  142. package/map/client/components/catalog/KLayerItem.vue +12 -2
  143. package/map/client/components/catalog/KLayersList.vue +180 -0
  144. package/map/client/components/catalog/KLayersPanel.vue +146 -36
  145. package/map/client/components/catalog/KLayersSelector.vue +96 -48
  146. package/map/client/components/catalog/KProjectEditor.vue +0 -9
  147. package/map/client/components/catalog/KProjectSelector.vue +3 -2
  148. package/map/client/components/catalog/KProjectsPanel.vue +23 -8
  149. package/map/client/components/catalog/KViewsPanel.vue +18 -8
  150. package/map/client/components/catalog/KWeatherLayersSelector.vue +3 -3
  151. package/map/client/components/form/KDirectionField.vue +3 -6
  152. package/map/client/components/form/KLayerCategoryField.vue +2 -2
  153. package/map/client/components/form/KOwsServiceField.vue +25 -24
  154. package/map/client/components/form/KSelectLayersField.vue +4 -4
  155. package/map/client/components/form/KSelectViewsField.vue +4 -4
  156. package/map/client/components/legend/KLayerLegend.vue +11 -2
  157. package/map/client/components/legend/KLegend.vue +44 -51
  158. package/map/client/components/location/KLocationCardSection.vue +6 -7
  159. package/map/client/components/location/KLocationMap.vue +23 -13
  160. package/map/client/components/stickies/KPosition.vue +5 -0
  161. package/map/client/components/styles/KLayerStyleAction.vue +59 -12
  162. package/map/client/components/styles/KStyleEditor.vue +71 -8
  163. package/map/client/components/styles/KStyleEditorSection.vue +82 -33
  164. package/map/client/components/styles/KStyleManager.vue +119 -59
  165. package/map/client/components/styles/KStylePreview.vue +9 -25
  166. package/map/client/components/styles/KStylePreviewItem.vue +22 -1
  167. package/map/client/components/tools/KSearchTool.vue +1 -1
  168. package/map/client/components/widget/KElevationProfile.vue +20 -17
  169. package/map/client/components/widget/KInformationBox.vue +5 -5
  170. package/map/client/components/widget/KMapillaryViewer.vue +2 -1
  171. package/map/client/components/widget/KTimeSeries.vue +11 -9
  172. package/map/client/globe.js +2 -0
  173. package/map/client/i18n/map_en.json +29 -7
  174. package/map/client/i18n/map_fr.json +29 -7
  175. package/map/client/leaflet/GradientPath.js +61 -24
  176. package/map/client/leaflet/ShapeMarker.js +12 -5
  177. package/map/client/leaflet/TiledMeshLayer.js +3 -3
  178. package/map/client/leaflet/utils/utils.geojson.js +66 -8
  179. package/map/client/leaflet/utils/utils.style.js +14 -15
  180. package/map/client/mixins/globe/mixin.base-globe.js +181 -34
  181. package/map/client/mixins/globe/mixin.file-layers.js +3 -0
  182. package/map/client/mixins/globe/mixin.geojson-layers.js +179 -31
  183. package/map/client/mixins/globe/mixin.opendap-layers.js +2 -1
  184. package/map/client/mixins/globe/mixin.style.js +23 -1
  185. package/map/client/mixins/globe/mixin.tooltip.js +14 -2
  186. package/map/client/mixins/map/mixin.base-map.js +146 -58
  187. package/map/client/mixins/map/mixin.edit-layers.js +18 -15
  188. package/map/client/mixins/map/mixin.geojson-layers.js +181 -106
  189. package/map/client/mixins/map/mixin.heatmap-layers.js +3 -2
  190. package/map/client/mixins/map/mixin.map-activity.js +6 -1
  191. package/map/client/mixins/map/mixin.mapillary-layers.js +2 -1
  192. package/map/client/mixins/map/mixin.pmtiles-layers.js +3 -3
  193. package/map/client/mixins/map/mixin.tiled-mesh-layers.js +3 -2
  194. package/map/client/mixins/map/mixin.tiled-wind-layers.js +3 -2
  195. package/map/client/mixins/mixin.activity.js +197 -51
  196. package/map/client/mixins/mixin.context.js +11 -11
  197. package/map/client/mixins/mixin.feature-service.js +11 -9
  198. package/map/client/mixins/mixin.weacast.js +5 -3
  199. package/map/client/readers/reader.geojson.js +3 -1
  200. package/map/client/utils/utils.capture.js +3 -3
  201. package/map/client/utils/utils.catalog.js +9 -5
  202. package/map/client/utils/utils.features.js +120 -54
  203. package/map/client/utils/utils.js +25 -10
  204. package/map/client/utils/utils.layers.js +148 -24
  205. package/map/client/utils/utils.location.js +26 -9
  206. package/map/client/utils/utils.schema.js +2 -1
  207. package/map/client/utils/utils.style.js +53 -9
  208. package/map/common/geotiff-grid-source.js +1 -3
  209. package/map/common/opendap-utils.js +0 -1
  210. package/map/common/tms-utils.js +0 -1
  211. package/map/common/wcs-utils.js +0 -1
  212. package/map/common/wfs-utils.js +0 -1
  213. package/map/common/wms-utils.js +7 -1
  214. package/map/common/wmts-utils.js +0 -1
  215. package/package.json +12 -12
  216. package/scripts/init_runner.sh +3 -3
  217. package/scripts/kash/CHANGELOG.md +27 -0
  218. package/scripts/kash/kash.sh +556 -237
  219. package/scripts/kash/scripts/run_tests.sh +44 -5
  220. package/scripts/setup_workspace.sh +23 -13
  221. package/test/api/core/config/default.cjs +2 -1
  222. package/test/api/core/tags.test.js +62 -0
  223. package/test/api/map/config/default.cjs +2 -1
  224. package/test/api/map/config/layers.json +9 -0
  225. package/test/api/map/data/openradiation.json +13811 -0
  226. package/test/api/map/grid-sources.test.js +1 -3
  227. package/test/api/map/index.test.js +60 -1
  228. package/test/api/map/style.test.js +30 -1
  229. package/test.api.js +1 -1
  230. package/vite/App.vue +18 -0
  231. package/vite/AppWithGlobe.vue +84 -0
  232. package/vite/GlobeActivity.vue +58 -0
  233. package/vite/MapActivity.vue +63 -0
  234. package/vite/MapActivityWithGlobe.vue +63 -0
  235. package/vite/README.md +169 -0
  236. package/vite/config.js +221 -0
  237. package/vite/index_with_globe.html +50 -0
  238. package/vite/index_with_map.html +50 -0
  239. package/vite/package.json +173 -0
  240. package/vite/quasar.variables.scss +17 -0
  241. package/vite/vite.config.js +166 -0
  242. package/vite/yarn.lock +11641 -0
  243. package/core/client/components/media/KImageViewer.vue +0 -68
  244. package/core/client/components/media/KMarkdownViewer.vue +0 -55
  245. package/core/client/components/media/KMediaBrowser.vue +0 -301
  246. package/coverage/base.css +0 -224
  247. package/coverage/block-navigation.js +0 -87
  248. package/coverage/core/api/application.js.html +0 -1870
  249. package/coverage/core/api/authentication.js.html +0 -874
  250. package/coverage/core/api/db.js.html +0 -793
  251. package/coverage/core/api/hooks/hooks.authentication.js.html +0 -139
  252. package/coverage/core/api/hooks/hooks.authorisations.js.html +0 -958
  253. package/coverage/core/api/hooks/hooks.groups.js.html +0 -229
  254. package/coverage/core/api/hooks/hooks.logger.js.html +0 -163
  255. package/coverage/core/api/hooks/hooks.model.js.html +0 -967
  256. package/coverage/core/api/hooks/hooks.organisations.js.html +0 -541
  257. package/coverage/core/api/hooks/hooks.push.js.html +0 -265
  258. package/coverage/core/api/hooks/hooks.query.js.html +0 -862
  259. package/coverage/core/api/hooks/hooks.schemas.js.html +0 -298
  260. package/coverage/core/api/hooks/hooks.service.js.html +0 -319
  261. package/coverage/core/api/hooks/hooks.storage.js.html +0 -193
  262. package/coverage/core/api/hooks/hooks.users.js.html +0 -595
  263. package/coverage/core/api/hooks/index.html +0 -266
  264. package/coverage/core/api/hooks/index.js.html +0 -115
  265. package/coverage/core/api/index.html +0 -176
  266. package/coverage/core/api/index.js.html +0 -148
  267. package/coverage/core/api/marshall.js.html +0 -448
  268. package/coverage/core/api/models/groups.model.mongodb.js.html +0 -109
  269. package/coverage/core/api/models/index.html +0 -131
  270. package/coverage/core/api/models/messages.model.mongodb.js.html +0 -121
  271. package/coverage/core/api/models/organisations.model.mongodb.js.html +0 -94
  272. package/coverage/core/api/models/tags.model.mongodb.js.html +0 -115
  273. package/coverage/core/api/models/users.model.mongodb.js.html +0 -115
  274. package/coverage/core/api/services/account/account.hooks.js.html +0 -208
  275. package/coverage/core/api/services/account/account.service.js.html +0 -436
  276. package/coverage/core/api/services/account/index.html +0 -131
  277. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +0 -184
  278. package/coverage/core/api/services/authorisations/authorisations.service.js.html +0 -520
  279. package/coverage/core/api/services/authorisations/index.html +0 -131
  280. package/coverage/core/api/services/databases/databases.hooks.js.html +0 -193
  281. package/coverage/core/api/services/databases/databases.service.js.html +0 -100
  282. package/coverage/core/api/services/databases/index.html +0 -131
  283. package/coverage/core/api/services/groups/groups.hooks.js.html +0 -178
  284. package/coverage/core/api/services/groups/index.html +0 -116
  285. package/coverage/core/api/services/import-export/import-export.hooks.js.html +0 -184
  286. package/coverage/core/api/services/import-export/import-export.service.js.html +0 -118
  287. package/coverage/core/api/services/import-export/index.html +0 -131
  288. package/coverage/core/api/services/index.html +0 -116
  289. package/coverage/core/api/services/index.js.html +0 -532
  290. package/coverage/core/api/services/mailer/index.html +0 -131
  291. package/coverage/core/api/services/mailer/mailer.hooks.js.html +0 -190
  292. package/coverage/core/api/services/mailer/mailer.service.js.html +0 -118
  293. package/coverage/core/api/services/messages/index.html +0 -116
  294. package/coverage/core/api/services/messages/messages.hooks.js.html +0 -202
  295. package/coverage/core/api/services/organisations/index.html +0 -131
  296. package/coverage/core/api/services/organisations/organisations.hooks.js.html +0 -178
  297. package/coverage/core/api/services/organisations/organisations.service.js.html +0 -343
  298. package/coverage/core/api/services/push/index.html +0 -131
  299. package/coverage/core/api/services/push/push.hooks.js.html +0 -190
  300. package/coverage/core/api/services/push/push.service.js.html +0 -121
  301. package/coverage/core/api/services/storage/index.html +0 -131
  302. package/coverage/core/api/services/storage/storage.hooks.js.html +0 -190
  303. package/coverage/core/api/services/storage/storage.service.js.html +0 -172
  304. package/coverage/core/api/services/tags/index.html +0 -116
  305. package/coverage/core/api/services/tags/tags.hooks.js.html +0 -178
  306. package/coverage/core/api/services/users/index.html +0 -131
  307. package/coverage/core/api/services/users/users.hooks.js.html +0 -310
  308. package/coverage/core/api/services/users/users.service.js.html +0 -100
  309. package/coverage/core/api/utils.js.html +0 -118
  310. package/coverage/core/common/errors.js.html +0 -88
  311. package/coverage/core/common/index.html +0 -191
  312. package/coverage/core/common/index.js.html +0 -115
  313. package/coverage/core/common/permissions.js.html +0 -733
  314. package/coverage/core/common/schema.js.html +0 -190
  315. package/coverage/core/common/utils.js.html +0 -226
  316. package/coverage/core/common/utils.offline.js.html +0 -199
  317. package/coverage/favicon.png +0 -0
  318. package/coverage/index.html +0 -476
  319. package/coverage/lcov-report/base.css +0 -224
  320. package/coverage/lcov-report/block-navigation.js +0 -87
  321. package/coverage/lcov-report/core/api/application.js.html +0 -1870
  322. package/coverage/lcov-report/core/api/authentication.js.html +0 -874
  323. package/coverage/lcov-report/core/api/db.js.html +0 -793
  324. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +0 -139
  325. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +0 -958
  326. package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +0 -229
  327. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +0 -163
  328. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +0 -967
  329. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +0 -541
  330. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +0 -265
  331. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +0 -862
  332. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +0 -298
  333. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +0 -319
  334. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +0 -193
  335. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +0 -595
  336. package/coverage/lcov-report/core/api/hooks/index.html +0 -266
  337. package/coverage/lcov-report/core/api/hooks/index.js.html +0 -115
  338. package/coverage/lcov-report/core/api/index.html +0 -176
  339. package/coverage/lcov-report/core/api/index.js.html +0 -148
  340. package/coverage/lcov-report/core/api/marshall.js.html +0 -448
  341. package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +0 -109
  342. package/coverage/lcov-report/core/api/models/index.html +0 -131
  343. package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +0 -121
  344. package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +0 -94
  345. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +0 -115
  346. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +0 -115
  347. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +0 -208
  348. package/coverage/lcov-report/core/api/services/account/account.service.js.html +0 -436
  349. package/coverage/lcov-report/core/api/services/account/index.html +0 -131
  350. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +0 -184
  351. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +0 -520
  352. package/coverage/lcov-report/core/api/services/authorisations/index.html +0 -131
  353. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +0 -193
  354. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +0 -100
  355. package/coverage/lcov-report/core/api/services/databases/index.html +0 -131
  356. package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +0 -178
  357. package/coverage/lcov-report/core/api/services/groups/index.html +0 -116
  358. package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +0 -184
  359. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +0 -118
  360. package/coverage/lcov-report/core/api/services/import-export/index.html +0 -131
  361. package/coverage/lcov-report/core/api/services/index.html +0 -116
  362. package/coverage/lcov-report/core/api/services/index.js.html +0 -532
  363. package/coverage/lcov-report/core/api/services/mailer/index.html +0 -131
  364. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +0 -190
  365. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +0 -118
  366. package/coverage/lcov-report/core/api/services/messages/index.html +0 -116
  367. package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +0 -202
  368. package/coverage/lcov-report/core/api/services/organisations/index.html +0 -131
  369. package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +0 -178
  370. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +0 -343
  371. package/coverage/lcov-report/core/api/services/push/index.html +0 -131
  372. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +0 -190
  373. package/coverage/lcov-report/core/api/services/push/push.service.js.html +0 -121
  374. package/coverage/lcov-report/core/api/services/storage/index.html +0 -131
  375. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +0 -190
  376. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +0 -172
  377. package/coverage/lcov-report/core/api/services/tags/index.html +0 -116
  378. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +0 -178
  379. package/coverage/lcov-report/core/api/services/users/index.html +0 -131
  380. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +0 -310
  381. package/coverage/lcov-report/core/api/services/users/users.service.js.html +0 -100
  382. package/coverage/lcov-report/core/api/utils.js.html +0 -118
  383. package/coverage/lcov-report/core/common/errors.js.html +0 -88
  384. package/coverage/lcov-report/core/common/index.html +0 -191
  385. package/coverage/lcov-report/core/common/index.js.html +0 -115
  386. package/coverage/lcov-report/core/common/permissions.js.html +0 -733
  387. package/coverage/lcov-report/core/common/schema.js.html +0 -190
  388. package/coverage/lcov-report/core/common/utils.js.html +0 -226
  389. package/coverage/lcov-report/core/common/utils.offline.js.html +0 -199
  390. package/coverage/lcov-report/favicon.png +0 -0
  391. package/coverage/lcov-report/index.html +0 -476
  392. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +0 -553
  393. package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +0 -397
  394. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +0 -1294
  395. package/coverage/lcov-report/map/api/hooks/index.html +0 -161
  396. package/coverage/lcov-report/map/api/hooks/index.js.html +0 -94
  397. package/coverage/lcov-report/map/api/index.html +0 -131
  398. package/coverage/lcov-report/map/api/index.js.html +0 -139
  399. package/coverage/lcov-report/map/api/marshall.js.html +0 -178
  400. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +0 -106
  401. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +0 -169
  402. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +0 -196
  403. package/coverage/lcov-report/map/api/models/index.html +0 -176
  404. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +0 -109
  405. package/coverage/lcov-report/map/api/models/styles.model.mongodb.js.html +0 -112
  406. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +0 -274
  407. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +0 -610
  408. package/coverage/lcov-report/map/api/services/alerts/index.html +0 -131
  409. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +0 -328
  410. package/coverage/lcov-report/map/api/services/catalog/index.html +0 -116
  411. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +0 -1510
  412. package/coverage/lcov-report/map/api/services/daptiles/index.html +0 -116
  413. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +0 -310
  414. package/coverage/lcov-report/map/api/services/features/features.service.js.html +0 -544
  415. package/coverage/lcov-report/map/api/services/features/index.html +0 -131
  416. package/coverage/lcov-report/map/api/services/index.html +0 -116
  417. package/coverage/lcov-report/map/api/services/index.js.html +0 -1054
  418. package/coverage/lcov-report/map/api/services/projects/index.html +0 -116
  419. package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +0 -439
  420. package/coverage/lcov-report/map/api/services/styles/index.html +0 -116
  421. package/coverage/lcov-report/map/api/services/styles/styles.hooks.js.html +0 -196
  422. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +0 -466
  423. package/coverage/lcov-report/map/common/errors.js.html +0 -94
  424. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +0 -544
  425. package/coverage/lcov-report/map/common/grid.js.html +0 -1612
  426. package/coverage/lcov-report/map/common/index.html +0 -371
  427. package/coverage/lcov-report/map/common/index.js.html +0 -172
  428. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +0 -556
  429. package/coverage/lcov-report/map/common/moment-utils.js.html +0 -157
  430. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +0 -868
  431. package/coverage/lcov-report/map/common/opendap-utils.js.html +0 -826
  432. package/coverage/lcov-report/map/common/permissions.js.html +0 -130
  433. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +0 -418
  434. package/coverage/lcov-report/map/common/tms-utils.js.html +0 -274
  435. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +0 -364
  436. package/coverage/lcov-report/map/common/wcs-utils.js.html +0 -586
  437. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +0 -1033
  438. package/coverage/lcov-report/map/common/wfs-utils.js.html +0 -574
  439. package/coverage/lcov-report/map/common/wms-utils.js.html +0 -451
  440. package/coverage/lcov-report/map/common/wmts-utils.js.html +0 -547
  441. package/coverage/lcov-report/prettify.css +0 -1
  442. package/coverage/lcov-report/prettify.js +0 -2
  443. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  444. package/coverage/lcov-report/sorter.js +0 -196
  445. package/coverage/lcov.info +0 -11520
  446. package/coverage/map/api/hooks/hooks.catalog.js.html +0 -553
  447. package/coverage/map/api/hooks/hooks.features.js.html +0 -397
  448. package/coverage/map/api/hooks/hooks.query.js.html +0 -1294
  449. package/coverage/map/api/hooks/index.html +0 -161
  450. package/coverage/map/api/hooks/index.js.html +0 -94
  451. package/coverage/map/api/index.html +0 -131
  452. package/coverage/map/api/index.js.html +0 -139
  453. package/coverage/map/api/marshall.js.html +0 -178
  454. package/coverage/map/api/models/alerts.model.mongodb.js.html +0 -106
  455. package/coverage/map/api/models/catalog.model.mongodb.js.html +0 -169
  456. package/coverage/map/api/models/features.model.mongodb.js.html +0 -196
  457. package/coverage/map/api/models/index.html +0 -176
  458. package/coverage/map/api/models/projects.model.mongodb.js.html +0 -109
  459. package/coverage/map/api/models/styles.model.mongodb.js.html +0 -112
  460. package/coverage/map/api/services/alerts/alerts.hooks.js.html +0 -274
  461. package/coverage/map/api/services/alerts/alerts.service.js.html +0 -610
  462. package/coverage/map/api/services/alerts/index.html +0 -131
  463. package/coverage/map/api/services/catalog/catalog.hooks.js.html +0 -328
  464. package/coverage/map/api/services/catalog/index.html +0 -116
  465. package/coverage/map/api/services/daptiles/daptiles.service.js.html +0 -1510
  466. package/coverage/map/api/services/daptiles/index.html +0 -116
  467. package/coverage/map/api/services/features/features.hooks.js.html +0 -310
  468. package/coverage/map/api/services/features/features.service.js.html +0 -544
  469. package/coverage/map/api/services/features/index.html +0 -131
  470. package/coverage/map/api/services/index.html +0 -116
  471. package/coverage/map/api/services/index.js.html +0 -1054
  472. package/coverage/map/api/services/projects/index.html +0 -116
  473. package/coverage/map/api/services/projects/projects.hooks.js.html +0 -439
  474. package/coverage/map/api/services/styles/index.html +0 -116
  475. package/coverage/map/api/services/styles/styles.hooks.js.html +0 -196
  476. package/coverage/map/common/dynamic-grid-source.js.html +0 -466
  477. package/coverage/map/common/errors.js.html +0 -94
  478. package/coverage/map/common/geotiff-grid-source.js.html +0 -544
  479. package/coverage/map/common/grid.js.html +0 -1612
  480. package/coverage/map/common/index.html +0 -371
  481. package/coverage/map/common/index.js.html +0 -172
  482. package/coverage/map/common/meteo-model-grid-source.js.html +0 -556
  483. package/coverage/map/common/moment-utils.js.html +0 -157
  484. package/coverage/map/common/opendap-grid-source.js.html +0 -868
  485. package/coverage/map/common/opendap-utils.js.html +0 -826
  486. package/coverage/map/common/permissions.js.html +0 -130
  487. package/coverage/map/common/time-based-grid-source.js.html +0 -418
  488. package/coverage/map/common/tms-utils.js.html +0 -274
  489. package/coverage/map/common/wcs-grid-source.js.html +0 -364
  490. package/coverage/map/common/wcs-utils.js.html +0 -586
  491. package/coverage/map/common/weacast-grid-source.js.html +0 -1033
  492. package/coverage/map/common/wfs-utils.js.html +0 -574
  493. package/coverage/map/common/wms-utils.js.html +0 -451
  494. package/coverage/map/common/wmts-utils.js.html +0 -547
  495. package/coverage/prettify.css +0 -1
  496. package/coverage/prettify.js +0 -2
  497. package/coverage/sort-arrow-sprite.png +0 -0
  498. package/coverage/sorter.js +0 -196
  499. package/coverage/tmp/coverage-151198-1753351220086-0.json +0 -1
  500. package/coverage/tmp/coverage-151210-1753351220070-0.json +0 -1
  501. package/coverage/tmp/coverage-151221-1753351129816-0.json +0 -1
  502. package/coverage/tmp/coverage-151233-1753351129803-0.json +0 -1
  503. package/coverage/tmp/coverage-151240-1753351129770-0.json +0 -1
  504. package/coverage/tmp/coverage-151307-1753351220058-0.json +0 -1
  505. package/coverage/tmp/coverage-151319-1753351220044-0.json +0 -1
  506. package/coverage/tmp/coverage-151326-1753351220010-0.json +0 -1
  507. package/extras/tours/core/account-profile.js +0 -32
  508. package/extras/tours/core/account.js +0 -143
  509. package/extras/tours/core/add-member.js +0 -75
  510. package/extras/tours/core/add-tag.js +0 -13
  511. package/extras/tours/core/create-group.js +0 -19
  512. package/extras/tours/core/create-organisation.js +0 -19
  513. package/extras/tours/core/create-tag.js +0 -26
  514. package/extras/tours/core/edit-member-role.js +0 -13
  515. package/extras/tours/core/groups.js +0 -65
  516. package/extras/tours/core/join-group.js +0 -13
  517. package/extras/tours/core/login.js +0 -41
  518. package/extras/tours/core/members.js +0 -108
  519. package/extras/tours/core/register.js +0 -61
  520. package/extras/tours/core/send-reset-password.js +0 -14
  521. package/extras/tours/core/tags.js +0 -65
  522. package/extras/tours/map/catalog-panel.js +0 -112
  523. package/extras/tours/map/fab.js +0 -26
  524. package/extras/tours/map/navigation-bar.js +0 -187
  525. package/extras/tours/map/side-nav.js +0 -36
  526. package/test/api/core/test-log-2025-02-05.log +0 -23
  527. package/test/api/core/test-log-2025-05-21.log +0 -15
  528. package/test/api/core/test-log-2025-06-25.log +0 -9
  529. package/test/api/core/test-log-2025-07-24.log +0 -44
  530. package/test/api/map/test-log-2025-05-27.log +0 -13
  531. package/test/api/map/test-log-2025-06-23.log +0 -7
  532. package/test/api/map/test-log-2025-07-24.log +0 -11
  533. package/test/client/core/api.js +0 -361
  534. package/test/client/core/index.js +0 -9
  535. package/test/client/index.js +0 -4
  536. package/test/client/map/index.js +0 -5
  537. package/test.client.js +0 -1
  538. /package/{test/client/core/time.js → extras/tests/core/time.mjs} +0 -0
  539. /package/extras/tours/{map/add-layer.js → add-layer.js} +0 -0
  540. /package/extras/tours/{map/catalog-categories.js → catalog-categories.js} +0 -0
  541. /package/extras/tours/{map/connect-layer.js → connect-layer.js} +0 -0
  542. /package/extras/tours/{map/create-layer.js → create-layer.js} +0 -0
  543. /package/extras/tours/{map/create-view.js → create-view.js} +0 -0
  544. /package/extras/tours/{map/import-layer.js → import-layer.js} +0 -0
  545. /package/extras/tours/{map/timeline.js → pane.bottom.js} +0 -0
@@ -13,7 +13,7 @@
13
13
  :error-message="errorLabel"
14
14
  :error="hasError"
15
15
  :disable="disabled"
16
- clearable
16
+ :clearable="isClearable()"
17
17
  bottom-slots
18
18
  @clear="model=''">
19
19
  <!-- control -->
@@ -30,7 +30,7 @@
30
30
  </template>
31
31
  <!-- Helper -->
32
32
  <template v-if="hasHelper" v-slot:append>
33
- <k-action
33
+ <KAction
34
34
  :id="properties.name + '-helper'"
35
35
  :label="helperLabel"
36
36
  :icon="helperIcon"
@@ -47,6 +47,8 @@
47
47
  </template>
48
48
 
49
49
  <script>
50
+ import _ from 'lodash'
51
+ import { getHtmlColor } from '../../utils/utils.colors.js'
50
52
  import { baseField } from '../../mixins'
51
53
 
52
54
  export default {
@@ -56,15 +58,20 @@ export default {
56
58
  picker: false
57
59
  }
58
60
  },
61
+ computed: {
62
+ color () {
63
+ return getHtmlColor(this.model)
64
+ }
65
+ },
59
66
  methods: {
60
- emptyModel () {
61
- return ''
62
- },
63
67
  onReferenceCreated (ref) {
64
68
  // https://github.com/quasarframework/quasar/issues/8956
65
69
  if (ref) {
66
70
  ref.$el.onclick = () => { this.picker = true }
67
71
  }
72
+ },
73
+ isClearable () {
74
+ return _.get(this.properties, 'field.clearable', true)
68
75
  }
69
76
  }
70
77
  }
@@ -72,7 +79,7 @@ export default {
72
79
 
73
80
  <style lang="scss" scoped>
74
81
  .k-color-field {
75
- background-color: v-bind(model);
82
+ background-color: v-bind(color);
76
83
  height: 16px;
77
84
  border-radius: 5px;
78
85
  }
@@ -7,11 +7,11 @@
7
7
  :id="properties.name + '-field'"
8
8
  v-model="model"
9
9
  :label="label"
10
- :options="options"
10
+ :options="getOptions()"
11
11
  options-selected-class="hidden"
12
12
  emit-value
13
13
  map-options
14
- :clearable="clearable"
14
+ :clearable="isClearable()"
15
15
  :error="hasError"
16
16
  :error-message="errorLabel"
17
17
  :disable="disabled"
@@ -76,20 +76,15 @@ export default {
76
76
  KColorScale
77
77
  },
78
78
  mixins: [baseField],
79
- computed: {
80
- clearable () {
81
- return _.get(this.properties, 'field.clearable', true)
82
- },
83
- options () {
84
- return _.get(this.properties, 'field.options', [])
85
- }
86
- },
87
79
  methods: {
88
80
  getId (option) {
89
81
  return _.kebabCase(option.name)
90
82
  },
91
- emptyModel () {
92
- return null
83
+ getOptions () {
84
+ return _.get(this.properties, 'field.options', [])
85
+ },
86
+ isClearable () {
87
+ return _.get(this.properties, 'field.clearable', true)
93
88
  }
94
89
  }
95
90
  }
@@ -1,34 +1,36 @@
1
1
  <template>
2
2
  <div v-if="readOnly" :id="properties.name + '-field'">
3
- <q-chip v-if="model.name" icon="las la-cloud-upload-alt">
3
+ <q-chip v-if="!multiple && model?.name">
4
4
  {{ model.name }}
5
5
  </q-chip>
6
+ <q-chip v-else
7
+ v-for="file in model"
8
+ :key="file.name"
9
+ icon="las la-cloud-upload-alt"
10
+ >
11
+ {{ file.name }}
12
+ </q-chip>
6
13
  </div>
7
- <!-- -->
8
- <q-field v-else-if="model"
9
- :for="properties.name + '-field'"
10
- v-model="model"
11
- :label="label"
12
- clearable
13
- @clear="onFileCleared"
14
- :disable="disabled"
15
- >
16
- <template v-slot:control>
17
- {{ model.name }}
18
- </template>
19
- </q-field>
20
14
  <q-file v-else
21
15
  :for="properties.name + '-field'"
22
- v-model="file"
16
+ v-model="files"
23
17
  :label="label"
24
- :accept="acceptedTypes"
18
+ :accept="getAcceptedTypes()"
25
19
  :filter="filterSelectedFiles"
26
20
  :error="hasError"
27
21
  :error-message="errorLabel"
28
22
  bottom-slots
29
23
  :disable="disabled"
30
- @update:model-value="onFileChanged"
31
- @rejected="onFileRejected">
24
+ :multiple="multiple"
25
+ :append="multiple"
26
+ :use-chips="true"
27
+ :clearable="isClearable()"
28
+ :max-files="getMaxFiles()"
29
+ :max-file-size="getMaxFileSize()"
30
+ :max-total-size="getMaxTotalSize()"
31
+ @update:model-value="onFilesChanged"
32
+ @rejected="onFileRejected"
33
+ >
32
34
  <!-- Helper -->
33
35
  <template v-if="hasHelper" v-slot:append>
34
36
  <KAction
@@ -50,117 +52,144 @@
50
52
  import _ from 'lodash'
51
53
  import logger from 'loglevel'
52
54
  import { markRaw } from 'vue'
55
+ import { Notify } from 'quasar'
53
56
  import { baseField } from '../../mixins'
54
57
  import { i18n } from '../../i18n.js'
55
58
  import { Reader } from '../../reader.js'
56
59
  import { Storage } from '../../storage.js'
60
+ import { formatSize } from '../../utils/utils.files.js'
57
61
 
58
62
  export default {
59
63
  mixins: [baseField],
60
64
  data () {
61
65
  return {
62
- file: null,
66
+ files: null,
63
67
  changed: false
64
68
  }
65
69
  },
66
70
  computed: {
67
- acceptedTypes () {
68
- return _.get(this.properties, 'field.mimeTypes', '')
69
- },
70
- maxFileSize () {
71
- return _.get(this.properties, 'field.maxSize', 1024 * 1024)
71
+ multiple () {
72
+ return _.get(this.properties, 'field.multiple', false)
72
73
  }
73
74
  },
74
75
  methods: {
75
76
  emptyModel () {
76
- return null
77
+ return this.multiple ? [] : null
78
+ },
79
+ getAcceptedTypes () {
80
+ return _.get(this.properties, 'field.mimeTypes', '')
81
+ },
82
+ getMaxFiles () {
83
+ return _.get(this.properties, 'field.maxFiles', this.multiple ? 9 : 1)
84
+ },
85
+ getMaxFileSize () {
86
+ return _.get(this.properties, 'field.maxFileSize', 1048576)
87
+ },
88
+ getMaxTotalSize () {
89
+ return _.get(this.properties, 'field.maxTotalSize', this.getMaxFileSize())
90
+ },
91
+ isClearable () {
92
+ return _.get(this.properties, 'field.clearable', true)
77
93
  },
78
94
  filterSelectedFiles (files) {
79
95
  const filter = _.get(this.properties, 'field.filter')
80
96
  if (!filter) return files
81
- return _.filter(files, file => { return file.name.includes(filter) })
82
- },
83
- onFileCleared () {
84
- this.file = null
85
- this.error = ''
86
- this.onChanged()
97
+ return _.filter(files, file => file.name.includes(filter))
87
98
  },
88
- async onFileChanged () {
89
- if (this.file) {
90
- // Check the size to display an explicit message
91
- if (this.file.size < this.maxFileSize) {
92
- // Check whether the file will be uploaded without being read
93
- if (!_.get(this.properties, 'field.readContent', true)) {
94
- this.model = { name: this.file.name, type: this.file.type }
95
- this.onChanged()
96
- this.changed = true
97
- return
98
- }
99
- // Check whether the file type is registered to be read by a reader
100
- const acceptedFiles = Reader.filter([this.file])
101
- if (acceptedFiles.length === 1) {
102
- const file = acceptedFiles[0]
103
- try {
104
- const content = await Reader.read(file)
105
- // Avoid making file content reactive as it might be large and it is not used in UI
106
- this.model = { name: this.file.name, type: this.file.type, content: markRaw(content) }
107
- this.onChanged()
108
- this.changed = true
109
- } catch (error) {
110
- this.error = error
111
- this.model = this.emptyModel()
112
- }
113
- } else {
114
- this.error = 'KFileField.INVALID_FILE_TYPE'
115
- this.model = this.emptyModel()
116
- }
117
- } else {
118
- this.error = 'KFileField.INVALID_FILE_SIZE'
119
- this.model = this.emptyModel()
99
+ async onFilesChanged () {
100
+ if (_.isEmpty(this.files)) {
101
+ // field cleared
102
+ this.model = this.emptyModel()
103
+ return
104
+ }
105
+ // field updated
106
+ const selectedFiles = this.multiple ? this.files : [this.files]
107
+ const result = []
108
+ for (const file of selectedFiles) {
109
+ // Check whether the file will be uploaded without being read
110
+ if (!_.get(this.properties, 'field.readContent', true)) {
111
+ result.push({ name: file.name, type: file.type, File: file })
112
+ continue
120
113
  }
114
+ // Check whether the file type is registered to be read by a reader
115
+ const accepted = Reader.filter([file])
116
+ if (accepted.length === 1) {
117
+ try {
118
+ const content = await Reader.read(accepted[0])
119
+ // Avoid making file content reactive as it might be large and it is not used in UI
120
+ result.push({ name: file.name, type: file.type, content: markRaw(content), File: file })
121
+ } catch (err) {
122
+ this.error = err
123
+ }
124
+ } this.error = 'KFileField.INVALID_FILE_TYPE'
121
125
  }
126
+ if (this.multiple) this.model = result
127
+ else this.model = _.get(result, '0', null)
128
+ this.changed = true
129
+ this.onChanged()
122
130
  },
123
- onFileRejected (file) {
124
- this.error = 'KFileField.INVALID_FILE_TYPE'
131
+ onFileRejected (errs) {
132
+ console.log(errs)
133
+ const errors = [].concat(errs)
134
+ for (const error of errors) {
135
+ if (error?.failedPropValidation === 'max-files') this.error = i18n.tc('errors.MAX_FILES_REACHED', this.getMaxFiles())
136
+ else if (error?.failedPropValidation === 'max-file-size') this.error = i18n.t('errors.MAX_FILE_SIZE_REACHED', { file: error.file.name, maxSize: formatSize(this.getMaxFileSize()) })
137
+ else if (error?.failedPropValidation === 'max-total-size') this.error = i18n.t('errors.MAX_TOTAL_SIZE_FILES_REACHED', { maxSize: formatSize(this.getMaxTotalSize()) })
138
+ else if (error?.failedPropValidation !== 'duplicate') this.error = 'KFileField.INVALID_FILE_TYPE'
139
+ }
125
140
  },
126
141
  async apply (object, field) {
127
142
  // A template generates the final path for the file in storage based on object context so that we can only do it here
128
143
  // Check wether we need to upload file content
129
- if (this.model && _.get(this.properties, 'field.storage')) {
130
- let path = _.get(this.properties, 'field.storage.path')
131
- // The template generates the final path for the file in storage
132
- if (path) path = _.template(path)(Object.assign({}, { fileName: this.model.name }, object))
133
- this.model.key = path || this.model.name
144
+ const files = this.multiple ? this.model || [] : [this.model]
145
+ for (const file of files) {
146
+ if (file && _.get(this.properties, 'field.storage')) {
147
+ let path = _.get(this.properties, 'field.storage.path')
148
+ // The template generates the final path for the file in storage
149
+ if (path) path = _.template(path)({ ...object, fileName: file.name })
150
+ file.key = path || this.model.name
151
+ }
134
152
  }
135
153
  baseField.methods.apply.call(this, object, field)
136
154
  },
155
+ async upload (object, field) {
156
+ const files = this.multiple ? this.model || [] : [this.model]
157
+ const promises = files.map(async file => {
158
+ if (file && file.key) {
159
+ // The template generates the final context for storage service
160
+ let context = _.get(this.properties, 'field.storage.context')
161
+ if (context) context = _.template(context)({ ...object, fileName: file.name })
162
+ const query = _.get(this.properties, 'field.storage.uploadQuery')
163
+ logger.debug(`[KDK] Uploading file ${file.name} with key ${file.key}`)
164
+ return Storage.upload({
165
+ file: file.name,
166
+ type: file.type,
167
+ key: file.key,
168
+ blob: file.File,
169
+ context
170
+ }, { query })
171
+ }
172
+ })
173
+ return Promise.all(promises)
174
+ },
137
175
  async submitted (object, field) {
138
- // Check wether we need to upload file content
139
- if (this.changed && _.get(this.model, 'key')) {
176
+ // Check whether we need to upload file content
177
+ if (this.changed) {
140
178
  // The template generates the final context for storage service
141
- let context = _.get(this.properties, 'field.storage.context')
142
- if (context) context = _.template(context)(Object.assign({}, { fileName: this.model.name }, object))
143
- const query = _.get(this.properties, 'field.storage.uploadQuery')
144
- logger.debug(`[KDK] Uploading file ${this.model.name} with key ${this.model.key}`)
145
- Storage.upload({
146
- file: this.model.name,
147
- type: this.model.type,
148
- key: this.model.key,
149
- blob: this.file,
150
- context
151
- }, { query })
179
+ this.upload(object, field)
152
180
  .then(() => {
153
- this.$notify({
181
+ const files = this.multiple ? this.model : [this.model]
182
+ Notify.create({
154
183
  type: 'positive',
155
- message: i18n.t('KFileField.UPLOAD_FILE_SUCCEEDED',
156
- { file: this.model.name })
184
+ message: i18n.t('KFileField.UPLOAD_FILE_SUCCEEDED', {
185
+ file: files.map(f => f.name).join(', ')
186
+ })
157
187
  })
158
188
  })
159
189
  .catch(error => {
160
- this.$notify({
190
+ Notify.create({
161
191
  type: 'negative',
162
- message: i18n.t('KFileField.UPLOAD_FILE_ERRORED',
163
- { file: this.model.name })
192
+ message: i18n.t('KFileField.UPLOAD_FILE_ERRORED')
164
193
  })
165
194
  logger.error(error)
166
195
  })
@@ -1,5 +1,9 @@
1
1
  <template>
2
- <form v-if="schema" class="column">
2
+ <q-form
3
+ v-if="schema"
4
+ @submit.prevent="onSubmit"
5
+ class="column"
6
+ >
3
7
  <!--
4
8
  Non-grouped fields
5
9
  -->
@@ -63,7 +67,7 @@
63
67
  </q-card>
64
68
  </q-expansion-item>
65
69
  </template>
66
- </form>
70
+ </q-form>
67
71
  </template>
68
72
 
69
73
  <script setup>
@@ -87,6 +91,10 @@ const props = defineProps({
87
91
  type: [String, Array],
88
92
  default: () => null
89
93
  },
94
+ onSubmit: {
95
+ type: Function,
96
+ default: (event) => false
97
+ },
90
98
  dense: {
91
99
  type: Boolean,
92
100
  default: false
@@ -177,31 +185,35 @@ function hasFieldError (field, errors) {
177
185
  return null
178
186
  }
179
187
  async function build () {
188
+ if (!props.schema) throw new Error('Cannot build the form without schema')
180
189
  fields.value = []
181
190
  nbReadyFields.value = 0
182
191
  isReady.value = false
183
- if (!props.schema) throw new Error('Cannot build the form without schema')
184
192
  // As we have some async operations here and build() can be trigerred async
185
193
  // from different places (watch, mount, ...) we flag it to avoid reentrance
186
194
  buildInProgress = true
187
195
  // Compile the schema
188
196
  await compileSchema(props.schema, props.filter)
189
197
  // Build the fields
190
- _.forOwn(schema.value.properties, (field, property) => {
191
- // clone and configure the field
192
- const cloneField = _.clone(field)
193
- cloneField.name = property // assign a name to allow binding between properties and fields
194
- let component = _.get(field.field, 'component', '')
195
- if (!component) {
196
- // Provide a default component based on schema value type when none is specified
197
- if (field.type === 'number' || field.type === 'integer') { component = 'form/KNumberField' } else if (field.type === 'boolean') { component = 'form/KToggleField' } else if (field.type === 'string') { component = 'form/KTextField' }
198
- }
199
- cloneField.component = loadComponent(component)
200
- cloneField.reference = null // will be set once te field is rendered
201
- cloneField.required = _.includes(schema.value.required, property) // add extra required info
202
- // add the field to the list of fields to be rendered
203
- fields.value.push(cloneField)
204
- })
198
+ if (!_.isEmpty(schema.value.properties)) {
199
+ _.forOwn(schema.value.properties, (field, property) => {
200
+ // clone and configure the field
201
+ const cloneField = _.clone(field)
202
+ cloneField.name = property // assign a name to allow binding between properties and fields
203
+ let component = _.get(field.field, 'component', '')
204
+ if (!component) {
205
+ // Provide a default component based on schema value type when none is specified
206
+ if (field.type === 'number' || field.type === 'integer') component = 'form/KNumberField'
207
+ else if (field.type === 'boolean') component = 'form/KToggleField'
208
+ else if (field.type === 'string') component = 'form/KTextField'
209
+ }
210
+ cloneField.component = loadComponent(component)
211
+ cloneField.reference = null // will be set once te field is rendered
212
+ cloneField.required = _.includes(schema.value.required, property) // add extra required info
213
+ // add the field to the list of fields to be rendered
214
+ fields.value.push(cloneField)
215
+ })
216
+ } else isReady.value = true
205
217
  buildInProgress = false
206
218
  }
207
219
  function values () {
@@ -8,7 +8,7 @@
8
8
  :id="properties.name + '-field'"
9
9
  v-model="model"
10
10
  :label="label"
11
- clearable
11
+ :clearable="isClearable()"
12
12
  :error-message="errorLabel"
13
13
  :error="hasError"
14
14
  :disable="disabled"
@@ -91,6 +91,9 @@ export default {
91
91
  // We support icon without a color, in this case we have a string as model
92
92
  return (this.color ? { name: '', color: '' } : '')
93
93
  },
94
+ isClearable () {
95
+ return _.get(this.properties, 'field.clearable', true)
96
+ },
94
97
  onFocused () {
95
98
  if (this.isEmpty()) this.$refs.iconChooser.open(this.model)
96
99
  },
@@ -14,7 +14,7 @@
14
14
  :error-message="errorLabel"
15
15
  bottom-slot
16
16
  @blur="onChanged"
17
- @update:model-value="onChanged"
17
+ @update:model-value="onUpdated"
18
18
 
19
19
  >
20
20
  <!-- Helper -->
@@ -35,9 +35,16 @@
35
35
  </template>
36
36
 
37
37
  <script>
38
+ import _ from 'lodash'
38
39
  import { baseField } from '../../mixins'
39
40
 
40
41
  export default {
41
- mixins: [baseField]
42
+ mixins: [baseField],
43
+ methods: {
44
+ onUpdated (value) {
45
+ this.model = _.isNumber(value) ? value : null
46
+ this.onChanged()
47
+ }
48
+ }
42
49
  }
43
50
  </script>
@@ -16,7 +16,7 @@
16
16
  map-options
17
17
  use-input
18
18
  :dense="dense"
19
- :clearable="clearable"
19
+ :clearable="isClearable()"
20
20
  :error="hasError"
21
21
  :error-message="errorLabel"
22
22
  :disable="disabled"
@@ -83,9 +83,6 @@ export default {
83
83
  multiple () {
84
84
  return this.isMultiselect()
85
85
  },
86
- clearable () {
87
- return this.isClearable()
88
- },
89
86
  chips () {
90
87
  return this.hasChips()
91
88
  },