@kalisio/kdk 2.1.9 → 2.2.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 (243) hide show
  1. package/.travis.test.sh +42 -10
  2. package/README.md +2 -2
  3. package/core/api/application.js +6 -1
  4. package/core/api/authentication.js +17 -1
  5. package/core/api/db.js +7 -2
  6. package/core/api/hooks/hooks.authentication.js +4 -2
  7. package/core/api/hooks/hooks.authorisations.js +12 -2
  8. package/core/api/hooks/hooks.model.js +5 -5
  9. package/core/api/hooks/hooks.organisations.js +0 -4
  10. package/core/api/services/account/account.hooks.js +10 -6
  11. package/core/api/services/account/account.service.js +1 -1
  12. package/{map/api/services/geocoder/geocoder.hooks.js → core/api/services/import-export/import-export.hooks.js} +7 -5
  13. package/core/api/services/import-export/import-export.service.js +11 -0
  14. package/core/api/services/index.js +13 -1
  15. package/core/api/services/users/users.hooks.js +2 -3
  16. package/core/client/api.js +16 -14
  17. package/core/client/capabilities.js +6 -2
  18. package/core/client/components/KContent.vue +11 -1
  19. package/core/client/components/KDialog.vue +17 -15
  20. package/core/client/components/KSponsor.vue +1 -1
  21. package/core/client/components/KTextArea.vue +5 -1
  22. package/core/client/components/app/KAbout.vue +1 -2
  23. package/core/client/components/app/KWelcome.vue +3 -5
  24. package/core/client/components/chart/KTimeSeriesChart.vue +24 -37
  25. package/core/client/components/collection/KColumn.vue +20 -17
  26. package/core/client/components/editor/KModalEditor.vue +0 -2
  27. package/core/client/components/form/KChipsField.vue +12 -2
  28. package/core/client/components/form/KColorField.vue +12 -2
  29. package/core/client/components/form/KColorScaleField.vue +12 -2
  30. package/core/client/components/form/KDateTimeRangeField.vue +12 -2
  31. package/core/client/components/form/KDatetimeField.vue +12 -2
  32. package/core/client/components/form/KEmailField.vue +12 -2
  33. package/core/client/components/form/KFileField.vue +12 -2
  34. package/core/client/components/form/KForm.vue +43 -9
  35. package/core/client/components/form/KIconField.vue +12 -2
  36. package/core/client/components/form/KItemField.vue +25 -4
  37. package/core/client/components/form/KNumberField.vue +12 -2
  38. package/core/client/components/form/KOptionsField.vue +12 -2
  39. package/core/client/components/form/KPasswordField.vue +12 -2
  40. package/core/client/components/form/KPhoneField.vue +13 -3
  41. package/core/client/components/form/KPropertyItemField.vue +12 -2
  42. package/core/client/components/form/KResolutionField.vue +126 -0
  43. package/core/client/components/form/KRoleField.vue +12 -2
  44. package/core/client/components/form/KSelectField.vue +14 -4
  45. package/core/client/components/form/KTextField.vue +12 -2
  46. package/core/client/components/form/KTextareaField.vue +13 -3
  47. package/core/client/components/form/KToggleField.vue +12 -2
  48. package/core/client/components/form/KTokenField.vue +12 -2
  49. package/core/client/components/form/KUnitField.vue +12 -2
  50. package/core/client/components/form/KUrlField.vue +12 -2
  51. package/core/client/components/input/KIconChooser.vue +10 -12
  52. package/core/client/components/input/KPalette.vue +2 -1
  53. package/core/client/components/layout/KPage.vue +5 -4
  54. package/core/client/components/layout/KWindow.vue +10 -10
  55. package/core/client/components/media/KColorScale.vue +26 -20
  56. package/core/client/components/media/KImageViewer.vue +57 -33
  57. package/core/client/components/media/KShape.vue +14 -103
  58. package/core/client/components/screen/KRegisterScreen.vue +0 -1
  59. package/core/client/components/screen/KScreenFooter.vue +0 -18
  60. package/core/client/components/team/KAddMember.vue +16 -22
  61. package/core/client/components/team/KGroupsActivity.vue +14 -0
  62. package/core/client/components/team/KMembersActivity.vue +12 -0
  63. package/core/client/components/team/KTagsActivity.vue +14 -0
  64. package/core/client/components/time/KDateTime.vue +23 -7
  65. package/core/client/components/time/KTimeControl.vue +142 -0
  66. package/core/client/components/tool/KExportTool.vue +57 -0
  67. package/core/client/composables/collection.js +0 -1
  68. package/core/client/composables/pwa.js +0 -1
  69. package/core/client/composables/schema.js +1 -1
  70. package/core/client/composables/session.js +30 -6
  71. package/core/client/exporter.js +141 -0
  72. package/core/client/i18n/core_en.json +91 -23
  73. package/core/client/i18n/core_fr.json +92 -23
  74. package/core/client/index.js +3 -0
  75. package/core/client/layout.js +34 -14
  76. package/core/client/local-storage.js +8 -6
  77. package/core/client/mixins/index.js +0 -1
  78. package/core/client/mixins/mixin.base-field.js +24 -2
  79. package/core/client/mixins/mixin.object-proxy.js +0 -1
  80. package/core/client/search.js +2 -1
  81. package/core/client/services/index.js +2 -1
  82. package/core/client/services/local-settings.service.js +4 -4
  83. package/core/client/theme.js +3 -3
  84. package/core/client/time.js +4 -0
  85. package/core/client/units.js +149 -4
  86. package/core/client/utils/index.js +13 -6
  87. package/core/client/utils/utils.account.js +1 -1
  88. package/core/client/utils/utils.colors.js +43 -0
  89. package/core/client/utils/utils.platform.js +0 -1
  90. package/core/client/utils/utils.pwa.js +14 -14
  91. package/core/client/utils/utils.session.js +1 -1
  92. package/core/client/utils/utils.shapes.js +270 -0
  93. package/core/client/utils/utils.time.js +37 -0
  94. package/core/common/permissions.js +3 -0
  95. package/core/common/schemas/settings.update.json +50 -29
  96. package/extras/css/core.variables.scss +3 -1
  97. package/extras/tours/map/navigation-bar.js +17 -15
  98. package/extras/tours/map/timeline.js +33 -33
  99. package/map/api/config/categories.cjs +4 -1
  100. package/map/api/hooks/hooks.catalog.js +39 -0
  101. package/map/api/hooks/hooks.features.js +23 -3
  102. package/map/api/hooks/hooks.query.js +31 -10
  103. package/map/api/models/projects.model.mongodb.js +8 -0
  104. package/map/api/services/catalog/catalog.hooks.js +5 -3
  105. package/map/api/services/features/features.hooks.js +18 -6
  106. package/map/api/services/index.js +22 -6
  107. package/map/api/services/projects/projects.hooks.js +118 -0
  108. package/map/client/capture.js +16 -0
  109. package/map/client/cesium/utils/index.js +3 -0
  110. package/map/client/cesium/utils/utils.events.js +30 -0
  111. package/map/client/cesium/utils/utils.popup.js +17 -0
  112. package/map/client/cesium/{utils.js → utils/utils.style.js} +53 -49
  113. package/map/client/components/KCapture.vue +50 -0
  114. package/map/client/components/KCaptureTextArea.vue +53 -0
  115. package/map/client/components/KCompass.vue +2 -2
  116. package/map/client/components/KFeaturesChart.vue +1 -1
  117. package/map/client/components/KFeaturesFilter.vue +2 -2
  118. package/map/client/components/KLayerStyleForm.vue +256 -430
  119. package/map/client/components/KLevelSlider.vue +1 -1
  120. package/map/client/components/KNorth.vue +31 -0
  121. package/map/client/components/KProjectMenu.vue +88 -0
  122. package/map/client/components/KTimezoneMap.vue +36 -23
  123. package/map/client/components/catalog/KAddLayer.vue +3 -4
  124. package/map/client/components/catalog/KConnectLayer.vue +16 -4
  125. package/map/client/components/catalog/KCreateLayer.vue +1 -2
  126. package/map/client/components/catalog/KCreateProject.vue +100 -0
  127. package/map/client/components/catalog/KCreateView.vue +25 -2
  128. package/map/client/components/catalog/KLayersPanel.vue +24 -27
  129. package/map/client/components/catalog/KLayersSelector.vue +1 -1
  130. package/map/client/components/catalog/KProjectEditor.vue +91 -0
  131. package/map/client/components/catalog/KProjectManager.vue +60 -0
  132. package/map/client/components/catalog/KProjectSelector.vue +38 -0
  133. package/map/client/components/catalog/KProjectsPanel.vue +153 -0
  134. package/map/client/components/catalog/KSelectLayers.vue +96 -0
  135. package/map/client/components/catalog/KSelectViews.vue +96 -0
  136. package/map/client/components/catalog/KViewsPanel.vue +66 -30
  137. package/map/client/components/form/KDirectionField.vue +24 -5
  138. package/map/client/components/form/KLayerCategoryField.vue +12 -2
  139. package/map/client/components/form/KLocationField.vue +20 -5
  140. package/map/client/components/form/KOwsLayerField.vue +12 -2
  141. package/map/client/components/form/KOwsServiceField.vue +12 -2
  142. package/map/client/components/form/KSelectLayersField.vue +159 -0
  143. package/map/client/components/form/KSelectViewsField.vue +121 -0
  144. package/map/client/components/form/KTimezoneField.vue +24 -17
  145. package/map/client/components/legend/KColorScaleLegend.vue +1 -1
  146. package/map/client/components/legend/KLayerLegend.vue +61 -0
  147. package/map/client/components/legend/KLegend.vue +45 -44
  148. package/map/client/components/legend/KLegendRenderer.vue +5 -3
  149. package/map/client/components/legend/KSymbolsLegend.vue +12 -10
  150. package/map/client/components/legend/KVariablesLegend.vue +78 -0
  151. package/map/client/components/location/KGeocodersFilter.vue +2 -4
  152. package/map/client/components/location/KLocationMap.vue +48 -17
  153. package/map/client/components/location/KLocationSearch.vue +13 -3
  154. package/map/client/components/tools/KSearchTool.vue +17 -12
  155. package/map/client/components/widget/KElevationProfile.vue +16 -19
  156. package/map/client/components/widget/KMapillaryViewer.vue +21 -22
  157. package/map/client/components/widget/KTimeSeries.vue +35 -23
  158. package/map/client/composables/activity.js +15 -2
  159. package/map/client/composables/catalog.js +66 -0
  160. package/map/client/composables/highlight.js +56 -20
  161. package/map/client/composables/index.js +2 -0
  162. package/map/client/composables/location.js +25 -18
  163. package/map/client/composables/project.js +122 -0
  164. package/map/client/geolocation.js +1 -1
  165. package/map/client/globe.js +2 -0
  166. package/map/client/i18n/map_en.json +123 -76
  167. package/map/client/i18n/map_fr.json +124 -72
  168. package/map/client/index.js +3 -0
  169. package/map/client/init.js +17 -0
  170. package/map/client/leaflet/GSMaPLayer.js +16 -17
  171. package/map/client/leaflet/ShapeMarker.js +40 -0
  172. package/map/client/leaflet/TiledFeatureLayer.js +1 -1
  173. package/map/client/leaflet/TiledMeshLayer.js +11 -15
  174. package/map/client/leaflet/TiledWindLayer.js +6 -10
  175. package/map/client/leaflet/utils/index.js +4 -0
  176. package/map/client/leaflet/utils/utils.events.js +41 -0
  177. package/map/client/leaflet/utils/utils.popup.js +21 -0
  178. package/map/client/leaflet/utils/utils.style.js +191 -0
  179. package/map/client/leaflet/utils/utils.tiles.js +87 -0
  180. package/map/client/map.js +2 -0
  181. package/map/client/mixins/globe/mixin.base-globe.js +29 -21
  182. package/map/client/mixins/globe/mixin.geojson-layers.js +132 -69
  183. package/map/client/mixins/globe/mixin.popup.js +2 -1
  184. package/map/client/mixins/globe/mixin.style.js +6 -4
  185. package/map/client/mixins/globe/mixin.tooltip.js +8 -3
  186. package/map/client/mixins/map/mixin.base-map.js +13 -11
  187. package/map/client/mixins/map/mixin.edit-layers.js +15 -15
  188. package/map/client/mixins/map/mixin.forecast-layers.js +3 -1
  189. package/map/client/mixins/map/mixin.geojson-layers.js +56 -20
  190. package/map/client/mixins/map/mixin.georaster-layers.js +4 -11
  191. package/map/client/mixins/map/mixin.heatmap-layers.js +1 -1
  192. package/map/client/mixins/map/mixin.popup.js +2 -1
  193. package/map/client/mixins/map/mixin.style.js +4 -67
  194. package/map/client/mixins/map/mixin.tiled-mesh-layers.js +2 -1
  195. package/map/client/mixins/map/mixin.tiled-wind-layers.js +4 -2
  196. package/map/client/mixins/map/mixin.tooltip.js +2 -1
  197. package/map/client/mixins/mixin.activity.js +66 -191
  198. package/map/client/mixins/mixin.catalog-panel.js +6 -6
  199. package/map/client/mixins/mixin.context.js +12 -9
  200. package/map/client/mixins/mixin.feature-service.js +29 -300
  201. package/map/client/mixins/mixin.weacast.js +11 -17
  202. package/map/client/pixi-utils.js +1 -1
  203. package/map/client/planets.js +58 -0
  204. package/map/client/utils/index.js +6 -0
  205. package/map/client/utils/utils.capture.js +176 -0
  206. package/map/client/utils/utils.catalog.js +149 -0
  207. package/map/client/utils/utils.features.js +364 -0
  208. package/map/client/utils/utils.js +0 -151
  209. package/map/client/utils/utils.layers.js +174 -0
  210. package/map/client/utils/utils.location.js +91 -23
  211. package/map/client/utils/utils.project.js +8 -0
  212. package/map/client/utils/utils.schema.js +0 -1
  213. package/map/client/utils/utils.style.js +297 -0
  214. package/map/client/utils.all.js +2 -2
  215. package/map/client/utils.globe.js +1 -1
  216. package/map/client/utils.map.js +1 -1
  217. package/map/common/permissions.js +2 -0
  218. package/map/common/schemas/capture.create.json +132 -0
  219. package/map/common/schemas/projects.create.json +52 -0
  220. package/map/common/schemas/projects.update.json +52 -0
  221. package/package.json +6 -5
  222. package/test/api/core/account.test.js +20 -0
  223. package/test/api/core/config/default.cjs +16 -3
  224. package/test/api/core/import-export.test.js +86 -0
  225. package/test/api/core/test-log-2024-01-04.log +14 -0
  226. package/test/api/map/catalog.test.js +164 -0
  227. package/test/api/map/index.test.js +25 -61
  228. package/test/api/map/test-log-2024-01-04.log +2 -0
  229. package/test/api/map/test-log-2024-01-11.log +1 -0
  230. package/test/api/map/test-log-2024-01-25.log +19 -0
  231. package/test/client/core/layout.js +25 -5
  232. package/test/client/core/utils.js +7 -0
  233. package/test/client/map/catalog.js +78 -1
  234. package/test/client/map/time.js +2 -1
  235. package/core/client/components/screen/KEndpointScreen.vue +0 -80
  236. package/core/client/mixins/mixin.account.js +0 -61
  237. package/extras/icons/kdk.png +0 -0
  238. package/map/api/services/geocoder/geocoder.service.js +0 -79
  239. package/map/client/components/KCaptureToolbar.vue +0 -155
  240. package/map/client/components/KColorLegend.vue +0 -349
  241. package/map/client/components/KTimeline.vue +0 -293
  242. package/map/client/components/KUrlLegend.vue +0 -122
  243. package/map/client/leaflet/utils.js +0 -246
@@ -10,9 +10,10 @@
10
10
 
11
11
  <script setup>
12
12
  import _ from 'lodash'
13
+ import * as math from 'mathjs'
13
14
  import { computed, watch, onMounted } from 'vue'
14
15
  import { uid } from 'quasar'
15
- import chroma from 'chroma-js'
16
+ import { buildColorScale } from '../../utils/utils.colors'
16
17
 
17
18
  // props
18
19
  const props = defineProps({
@@ -21,7 +22,7 @@ const props = defineProps({
21
22
  default: undefined
22
23
  },
23
24
  colors: {
24
- type: String,
25
+ type: [String, Array],
25
26
  default: 'OrRd'
26
27
  },
27
28
  domain: {
@@ -50,7 +51,8 @@ const props = defineProps({
50
51
  ticks: {
51
52
  size: 10,
52
53
  font: 'Arial',
53
- color: 'black'
54
+ color: 'black',
55
+ format: { notation: 'auto', precision: 3 }
54
56
  }
55
57
  }
56
58
  }
@@ -64,14 +66,14 @@ const props = defineProps({
64
66
  }
65
67
  })
66
68
 
67
- // data
69
+ // Data
68
70
  const canvasId = uid()
69
71
  let canvas = null
70
72
  let canvasContext = null
71
73
  let expectedSize = null
72
74
  const callRefresh = _.debounce(() => { refresh() }, 200)
73
75
 
74
- // computed
76
+ // Computed
75
77
  const labelSize = computed(() => {
76
78
  return _.get(props.layout, 'label.size', 12)
77
79
  })
@@ -91,7 +93,7 @@ const barWidth = computed(() => {
91
93
  return _.get(props.layout, 'bar.width', props.direction === 'vertical' ? 16 : undefined)
92
94
  })
93
95
  const ticksSize = computed(() => {
94
- return _.get(props.layout, 'ticks.size', 8)
96
+ return _.get(props.layout, 'ticks.size', 10)
95
97
  })
96
98
  const ticksFont = computed(() => {
97
99
  return ticksSize.value + 'px ' + _.get(props.layout, 'ticks.font', 'Arial')
@@ -102,7 +104,11 @@ const ticksColor = computed(() => {
102
104
  const gutter = computed(() => {
103
105
  return _.get(props.layout, 'gutter', 4)
104
106
  })
105
- // functions
107
+
108
+ // Functions
109
+ function formatTick (tick) {
110
+ return math.format(tick, props.layout.ticks.format)
111
+ }
106
112
  function drawLabel () {
107
113
  if (_.isNil(props.label)) return
108
114
  canvasContext.font = labelFont.value
@@ -111,7 +117,7 @@ function drawLabel () {
111
117
  let xLabel = canvas.width
112
118
  switch (labelAlign.value) {
113
119
  case 'left':
114
- xLabel = 0
120
+ xLabel = 0
115
121
  break
116
122
  case 'center':
117
123
  xLabel = canvas.width / 2
@@ -126,9 +132,9 @@ function drawDiscreteHorizontalScale () {
126
132
  const yBar = _.isNil(props.label) ? 0 : labelSize.value + gutter.value
127
133
  const length = props.classes.length - 1
128
134
  const boxWidth = canvas.width / length
129
- const classToColor = chroma.scale(props.colors).classes(props.classes)
135
+ const colorScale = buildColorScale(props)
130
136
  for (let i = 0; i < length; i++) {
131
- canvasContext.fillStyle = classToColor(props.classes[i])
137
+ canvasContext.fillStyle = colorScale(props.classes[i])
132
138
  canvasContext.fillRect(i * boxWidth, yBar, boxWidth, barHeight.value)
133
139
  }
134
140
  // draw ticks
@@ -140,16 +146,16 @@ function drawDiscreteHorizontalScale () {
140
146
  if (i === 0) {
141
147
  if (props.classes[i] !== Number.MIN_VALUE) {
142
148
  canvasContext.textAlign = 'left'
143
- tick = props.classes[i]
149
+ tick = formatTick(props.classes[i])
144
150
  }
145
151
  } else if (i === props.classes.length - 1) {
146
152
  if (props.classes[i] !== Number.MAX_VALUE) {
147
153
  canvasContext.textAlign = 'right'
148
- tick = props.classes[i]
154
+ tick = formatTick(props.classes[i])
149
155
  }
150
156
  } else {
151
157
  canvasContext.textAlign = 'center'
152
- tick = props.classes[i]
158
+ tick = formatTick(props.classes[i])
153
159
  }
154
160
  if (tick) canvasContext.fillText(tick, i * boxWidth, yTicks)
155
161
  }
@@ -160,9 +166,9 @@ function drawDiscreteVerticalScale () {
160
166
  const yBar = _.isNil(props.label) ? 0 : labelSize.value + gutter.value
161
167
  const length = props.classes.length - 1
162
168
  const boxHeight = (canvas.height - yBar) / length
163
- const classToColor = chroma.scale(props.colors).classes(props.classes)
169
+ const colorScale = buildColorScale(props)
164
170
  for (let i = 0; i < length; i++) {
165
- canvasContext.fillStyle = classToColor(props.classes[i])
171
+ canvasContext.fillStyle = colorScale(props.classes[i])
166
172
  canvasContext.fillRect(0, yBar + (length - i - 1) * boxHeight, barWidth.value, boxHeight)
167
173
  }
168
174
  // draw ticks
@@ -173,10 +179,10 @@ function drawDiscreteVerticalScale () {
173
179
  for (let i = 0; i < props.classes.length; ++i) {
174
180
  let tick
175
181
  if (i === 0) {
176
- if (props.classes[i] !== Number.MIN_VALUE) tick = props.classes[i]
182
+ if (props.classes[i] !== Number.MIN_VALUE) tick = formatTick(props.classes[i])
177
183
  } else if (i === props.classes.length - 1) {
178
- if (props.classes[i] !== Number.MAX_VALUE) tick = props.classes[i]
179
- } else tick = props.classes[i]
184
+ if (props.classes[i] !== Number.MAX_VALUE) tick = formatTick(props.classes[i])
185
+ } else tick = formatTick(props.classes[i])
180
186
  if (tick) canvasContext.fillText(tick, x, yBar + (length - i) * boxHeight + ticksSize.value / 2)
181
187
  }
182
188
  }
@@ -185,7 +191,7 @@ function drawContinuousHorizontalScale () {
185
191
  // draw colorbar
186
192
  const yBar = _.isNil(props.label) ? 0 : labelSize.value + gutter.value
187
193
  const length = canvas.width
188
- const colors = chroma.scale(props.colors).colors(length)
194
+ const colors = buildColorScale(props).colors(length)
189
195
  for (let i = 0; i < length; i++) {
190
196
  canvasContext.fillStyle = colors[i]
191
197
  canvasContext.fillRect(i, yBar, 1, barHeight.value)
@@ -204,7 +210,7 @@ function drawContinuousVerticalScale () {
204
210
  // draw colorbar
205
211
  const yBar = _.isNil(props.label) ? 0 : labelSize.value + gutter.value
206
212
  const length = canvas.height - yBar
207
- const colors = chroma.scale(props.colors).colors(length)
213
+ const colors = buildColorScale(props).colors(length)
208
214
  for (let i = 0; i < length; i++) {
209
215
  canvasContext.fillStyle = colors[i]
210
216
  canvasContext.fillRect(0, yBar + length - i, barWidth.value, 1)
@@ -1,44 +1,68 @@
1
1
  <template>
2
- <div v-if="interactive === true" class="fit" >
3
- <pinch-zoom class="pinch-zoom-controller fit row justify-center items-center" @change="$emit('image-transformed')">
2
+ <div>
3
+ <div v-if="interactive === true" class="fit" >
4
+ <pinch-zoom class="pinch-zoom-controller fit row justify-center items-center" @change="$emit('image-transformed')">
5
+ <img :src="source" style="max-width:100%; max-height:100%" :onload="onLoaded" />
6
+ </pinch-zoom>
7
+
8
+ </div>
9
+ <div v-else class="fit row justify-center items-center">
4
10
  <img :src="source" style="max-width:100%; max-height:100%" />
5
- </pinch-zoom>
6
- </div>
7
- <div v-else class="fit row justify-center items-center">
8
- <img :src="source" style="max-width:100%; max-height:100%" />
11
+ </div>
12
+ <q-spinner
13
+ class="absolute-center"
14
+ v-if="loading"
15
+ color="white"
16
+ size="3em"
17
+ />
9
18
  </div>
10
19
  </template>
11
20
 
12
- <script>
21
+ <script setup>
22
+ import { ref, onMounted } from 'vue'
13
23
  import 'pinch-zoom-element/dist/pinch-zoom.js'
14
24
 
15
- export default {
16
- props: {
17
- source: {
18
- type: String,
19
- default: ''
20
- },
21
- interactive: {
22
- type: Boolean,
23
- default: true
24
- }
25
- },
26
- emits: ['image-transformed'],
27
- methods: {
28
- restore () {
29
- const controller = document.querySelector('.pinch-zoom-controller')
30
- if (controller) {
31
- controller.setTransform({
32
- scale: 1,
33
- x: 0,
34
- y: 0,
35
- allowChangeEvent: true
36
- })
37
- }
38
- }
25
+ // Props
26
+ defineProps({
27
+ source: {
28
+ type: String,
29
+ default: ''
39
30
  },
40
- mounted () {
41
- this.restore()
31
+ interactive: {
32
+ type: Boolean,
33
+ default: true
34
+ }
35
+ })
36
+
37
+ // Emit
38
+ defineEmits(['image-transformed'])
39
+
40
+ // Data
41
+ const loading = ref(true)
42
+
43
+ // Functions
44
+ function restore () {
45
+ const controller = document.querySelector('.pinch-zoom-controller')
46
+ if (controller) {
47
+ controller.setTransform({
48
+ scale: 1,
49
+ x: 0,
50
+ y: 0,
51
+ allowChangeEvent: true
52
+ })
42
53
  }
43
54
  }
55
+ function onLoaded () {
56
+ loading.value = false
57
+ }
58
+
59
+ // Hooks
60
+ onMounted(() => {
61
+ restore()
62
+ })
63
+
64
+ // Expose
65
+ defineExpose({
66
+ restore
67
+ })
44
68
  </script>
@@ -1,57 +1,6 @@
1
1
  <template>
2
2
  <div>
3
- <svg :width="width" :height="height" style="display:block">
4
- <circle
5
- v-if="type === 'circle'"
6
- :cx="width/2"
7
- :cy="height/2"
8
- :r="(Math.min(height, width)/2)-borderWidth"
9
- class="k-shape"
10
- />
11
- <ellipse
12
- v-if="type === 'ellipse'"
13
- :cx="width/2"
14
- :cy="height/2"
15
- :rx="(width/2)-borderWidth"
16
- :ry="(height/2)-borderWidth"
17
- class="k-shape"
18
- />
19
- <rect
20
- v-if="type === 'rect'"
21
- :x="borderWidth"
22
- :y="borderWidth"
23
- :width="width-(2*borderWidth)"
24
- :height="height-(2*borderWidth)"
25
- :rx="borderRadius"
26
- :ry="borderRadius"
27
- class="k-shape"
28
- />
29
- <polygon
30
- v-if="type === 'triangle-up'"
31
- :points="`${width/2},${borderWidth} ${borderWidth},${height-borderWidth} ${width-borderWidth},${height-borderWidth}`"
32
- class="k-shape"
33
- />
34
- <polygon
35
- v-if="type === 'triangle-down'"
36
- :points="`${width/2},${height-borderWidth} ${borderWidth},${borderWidth} ${width-borderWidth},${borderWidth}`"
37
- class="k-shape"
38
- />
39
- <polygon
40
- v-if="type === 'triangle-right'"
41
- :points="`0,0 0,${height} ${width},${height/2}`"
42
- class="k-shape"
43
- />
44
- <polygon
45
- v-if="type === 'triangle-left'"
46
- :points="`0,${(height-borderWidth)/2} ${width-borderWidth},${height-borderWidth} ${width-borderWidth},${borderWidth}`"
47
- class="k-shape"
48
- />
49
- <polygon
50
- v-if="type === 'diamond'"
51
- :points="`${width/2},${height-borderWidth} ${width-borderWidth},${height/2} ${width/2},${borderWidth} ${borderWidth},${height/2}`"
52
- class="k-shape"
53
- />
54
- </svg>
3
+ <div v-if="content" v-html="content" />
55
4
  <q-tooltip v-if="tooltip">
56
5
  {{ tooltip }}
57
6
  </q-tooltip>
@@ -59,62 +8,24 @@
59
8
  </template>
60
9
 
61
10
  <script setup>
62
- import { getCssVar } from 'quasar'
11
+ import { computed } from 'vue'
12
+ import { createShape } from '../../utils/utils.shapes.js'
63
13
 
64
- // props
65
- defineProps({
66
- type: {
67
- type: String,
68
- default: 'circle',
69
- validator: (value) => {
70
- return ['circle', 'ellipse', 'rect', 'triangle-up', 'triangle-down', 'triangle-right', 'triangle-left', 'diamond'].includes(value)
71
- }
72
- },
73
- width: {
74
- type: Number,
75
- default: 18
76
- },
77
- height: {
78
- type: Number,
79
- default: 18
80
- },
81
- color: {
82
- type: String,
83
- default: getCssVar('primary')
84
- },
85
- opacity: {
86
- type: Number,
87
- default: 1
88
- },
89
- borderColor: {
90
- type: String,
91
- default: 'black'
92
- },
93
- borderWidth: {
94
- type: Number,
95
- default: 1
96
- },
97
- borderRadius: {
98
- type: Number,
99
- default: 0
100
- },
101
- dashArray: {
102
- type: String,
103
- default: ''
14
+ // Props
15
+ const props = defineProps({
16
+ options: {
17
+ type: Object,
18
+ required: true
104
19
  },
105
20
  tooltip: {
106
21
  type: String,
107
22
  default: undefined
108
23
  }
109
24
  })
110
- </script>
111
25
 
112
- <style lang="scss" scoped>
113
- .k-shape {
114
- fill: v-bind(color);
115
- fill-opacity: v-bind(opacity);
116
- stroke: v-bind(borderColor);
117
- stroke-width: v-bind(borderWidth);
118
- stroke-dasharray: v-bind(dashArray);
119
- }
120
- </style>
26
+ // Computed
27
+ const content = computed(() => {
28
+ const shape = createShape(props.options)
29
+ return shape ? shape.html : undefined
30
+ })
31
+ </script>
@@ -87,7 +87,6 @@ function getFormSchema () {
87
87
  field: {
88
88
  component: 'form/KToggleField',
89
89
  label: i18n.t('KRegisterScreen.ACCEPT_TERMS_LABEL'),
90
- helper: i18n.t('KRegisterScreen.ACCEPT_TERMS_HELPER', { domain }),
91
90
  errorLabel: i18n.t('KRegisterScreen.ACCEPT_TERMS_ERROR_LABEL', { domain }),
92
91
  'checked-icon': 'check',
93
92
  'unchecked-icon': 'clear'
@@ -2,31 +2,13 @@
2
2
  <div class="q-pa-sm column justify-center q-gutter-sm">
3
3
  <!-- Version -->
4
4
  <KVersion />
5
- <!-- Endpoint -->
6
- <div v-if="canChangeEndpoint" class="row justify-center">
7
- <KAction
8
- class="text-caption"
9
- id="change-endpoint"
10
- label="KScreen.CHANGE_ENDPOINT_LINK"
11
- :route="{name: 'change-endpoint'}"
12
- />
13
- </div>
14
5
  <!-- Sponsor -->
15
6
  <KSponsor />
16
7
  </div>
17
8
  </template>
18
9
 
19
10
  <script setup>
20
- import { ref } from 'vue'
21
- import { useQuasar } from 'quasar'
22
- import { useVersion } from '../../composables'
23
11
  import KVersion from '../KVersion.vue'
24
- import KAction from '../KAction.vue'
25
12
  import KSponsor from '../KSponsor.vue'
26
13
 
27
- // Data
28
- const $q = useQuasar()
29
- const { Version } = useVersion()
30
- const canChangeEndpoint = ref(false)
31
- if (Version.value.flavor === 'dev' || $q.platform.is.cordova) canChangeEndpoint.value = true
32
14
  </script>
@@ -85,10 +85,12 @@
85
85
 
86
86
  <script>
87
87
  import _ from 'lodash'
88
- import logger from 'loglevel'
89
88
  import { Dialog, exportFile } from 'quasar'
90
89
  import { baseModal } from '../../mixins'
91
90
  import { getLocale } from '../../utils'
91
+ import { api } from '../../api.js'
92
+ import { Store } from '../../store.js'
93
+ import { i18n } from '../../i18n.js'
92
94
  import { RoleNames } from '../../../common/permissions'
93
95
  import KModal from '../KModal.vue'
94
96
  import KForm from '../form/KForm.vue'
@@ -315,19 +317,11 @@ export default {
315
317
  flat: true
316
318
  }
317
319
  }).onOk(async () => {
318
- try {
319
- await this.processRecords(records)
320
- } catch (error) {
321
- logger.error(error)
322
- }
320
+ this.processRecords(records)
323
321
  this.closeModal()
324
322
  })
325
323
  } else {
326
- try {
327
- await this.processRecords(records)
328
- } catch (error) {
329
- logger.error(error)
330
- }
324
+ this.processRecords(records)
331
325
  this.closeModal()
332
326
  }
333
327
  }
@@ -335,44 +329,44 @@ export default {
335
329
  },
336
330
  async processRecords (records) {
337
331
  const report = {}
338
- for (let i = 0; i < records.length; ++i) {
332
+ for (let i = 0; i < records.length; i++) {
339
333
  const record = records[i]
340
- report[record.name] = await this.processRecord(record)
334
+ report[record.name] = await this.processRecord(record, this.contextId)
341
335
  }
342
336
  exportFile('report.json', JSON.stringify(report, null, '\t'))
343
337
  },
344
- async processRecord (record) {
338
+ async processRecord (record, contextId) {
345
339
  // Check whether the guest has already an acount
346
- const usersService = this.$api.getService('users')
340
+ const usersService = api.getService('users')
347
341
  const response = await usersService.find({ query: { email: record.email } })
348
342
  if (response.total === 1) {
349
343
  // Check whether the user belong to the organisation
350
344
  const user = response.data[0]
351
- if (_.find(user.organisations, { _id: this.contextId })) return this.$t('KAddMember.ALREADY_MEMBER_ERROR')
345
+ if (_.find(user.organisations, { _id: contextId })) return i18n.t('KAddMember.ALREADY_MEMBER_ERROR')
352
346
  // Add the person
353
- const authorisationService = this.$api.getService('authorisations')
347
+ const authorisationService = api.getService('authorisations')
354
348
  await authorisationService.create({
355
349
  scope: 'organisations',
356
350
  permissions: record.role,
357
351
  subjects: user._id,
358
352
  subjectsService: 'users',
359
- resource: this.contextId,
353
+ resource: contextId,
360
354
  resourcesService: 'organisations'
361
355
  })
362
- return this.$t('KAddMember.USER_ADDED_MESSAGE')
356
+ return i18n.t('KAddMember.USER_ADDED_MESSAGE')
363
357
  } else {
364
358
  const guest = {
365
359
  locale: getLocale(),
366
360
  sponsor: {
367
- id: this.$store.get('user._id'),
368
- organisationId: this.contextId,
361
+ id: Store.get('user._id'),
362
+ organisationId: contextId,
369
363
  roleGranted: record.role
370
364
  },
371
365
  name: record.name,
372
366
  email: record.email
373
367
  }
374
368
  await usersService.create(guest)
375
- return this.$t('KAddMember.GUEST_ADDED_MESSAGE')
369
+ return i18n.t('KAddMember.GUEST_ADDED_MESSAGE')
376
370
  }
377
371
  }
378
372
  },
@@ -37,6 +37,7 @@ import KStamp from '../KStamp.vue'
37
37
 
38
38
  import _ from 'lodash'
39
39
  import { baseActivity } from '../../mixins'
40
+ import { Exporter } from '../../exporter.js'
40
41
 
41
42
  export default {
42
43
  name: 'groups-activity',
@@ -61,6 +62,19 @@ export default {
61
62
  component: 'team/KGroupCard'
62
63
  }, this.activityOptions.items)
63
64
  }
65
+ },
66
+ methods: {
67
+ exportGroups () {
68
+ Exporter.export({
69
+ service: 'groups',
70
+ context: this.contextId,
71
+ formats: [
72
+ { label: 'CSV', value: 'csv' },
73
+ { label: 'JSON', value: 'json' }
74
+ ],
75
+ gzip: false
76
+ })
77
+ }
64
78
  }
65
79
  }
66
80
  </script>
@@ -33,6 +33,7 @@ import KGrid from '../collection/KGrid.vue'
33
33
  import KStamp from '../KStamp.vue'
34
34
  import { baseActivity } from '../../mixins'
35
35
  import { getRoleForOrganisation } from '../../../common/permissions'
36
+ import { Exporter } from '../../exporter.js'
36
37
 
37
38
  const activityMixin = baseActivity()
38
39
 
@@ -105,6 +106,17 @@ export default {
105
106
  const usersService = this.$api.getService('users')
106
107
  usersService.off('patched', this.refresh)
107
108
  },
109
+ exportMembers () {
110
+ Exporter.export({
111
+ service: 'members',
112
+ context: this.contextId,
113
+ formats: [
114
+ { label: 'CSV', value: 'csv' },
115
+ { label: 'JSON', value: 'json' }
116
+ ],
117
+ gzip: false
118
+ })
119
+ },
108
120
  refresh (user) {
109
121
  const grid = this.$refs.membersGrid
110
122
  if (grid) {
@@ -32,6 +32,7 @@ import KPage from '../layout/KPage.vue'
32
32
  import KGrid from '../collection/KGrid.vue'
33
33
  import KStamp from '../KStamp.vue'
34
34
  import { baseActivity } from '../../mixins'
35
+ import { Exporter } from '../../exporter.js'
35
36
 
36
37
  export default {
37
38
  name: 'tags-activity',
@@ -56,6 +57,19 @@ export default {
56
57
  component: 'team/KTagCard'
57
58
  }, this.activityOptions.items)
58
59
  }
60
+ },
61
+ methods: {
62
+ exportTags () {
63
+ Exporter.export({
64
+ service: 'tags',
65
+ context: this.contextId,
66
+ formats: [
67
+ { label: 'CSV', value: 'csv' },
68
+ { label: 'JSON', value: 'json' }
69
+ ],
70
+ gzip: false
71
+ })
72
+ }
59
73
  }
60
74
  }
61
75
  </script>
@@ -7,6 +7,8 @@
7
7
  :disabled="disabled"
8
8
  :dense="dense"
9
9
  />
10
+ <!-- Separator -->
11
+ <div v-if="separator">{{ separator }}</div>
10
12
  <!-- Time -->
11
13
  <KTime
12
14
  v-model="timeModel"
@@ -21,6 +23,8 @@
21
23
  import _ from 'lodash'
22
24
  import moment from 'moment'
23
25
  import { ref, computed, watch } from 'vue'
26
+ import { toLocalTimezone } from '../../utils/utils.time.js'
27
+ import { Time } from '../../time.js'
24
28
  import KDate from './KDate.vue'
25
29
  import KTime from './KTime.vue'
26
30
 
@@ -34,6 +38,10 @@ const props = defineProps({
34
38
  return true
35
39
  }
36
40
  },
41
+ timezone: {
42
+ type: String,
43
+ default: null
44
+ },
37
45
  options: {
38
46
  type: Object,
39
47
  default: () => {}
@@ -109,16 +117,24 @@ const timeModel = computed({
109
117
  const timeOptions = computed(() => {
110
118
  return _.merge({}, _.get(props.options, 'time'), { picker: { options: checkTime } })
111
119
  })
120
+ const separator = computed(() => {
121
+ return _.get(props.options, 'separator')
122
+ })
112
123
 
113
124
  // Watch
114
125
  watch(() => props.modelValue, (value) => {
115
- dateTime.value = moment.utc(value).local()
126
+ dateTime.value = toLocalTimezone(props.modelValue, Time.getFormatTimezone())
127
+ })
128
+ watch(() => props.timezone, (value) => {
129
+ dateTime.value = toLocalTimezone(props.modelValue, Time.getFormatTimezone())
130
+ minDateTime.value = toLocalTimezone(props.min, Time.getFormatTimezone())
131
+ maxDateTime.value = toLocalTimezone(props.max, Time.getFormatTimezone())
116
132
  })
117
133
  watch(() => props.min, (value) => {
118
- minDateTime.value = moment.utc(value).local()
134
+ minDateTime.value = toLocalTimezone(props.min, Time.getFormatTimezone())
119
135
  })
120
136
  watch(() => props.max, (value) => {
121
- maxDateTime.value = moment.utc(value).local()
137
+ maxDateTime.value = toLocalTimezone(props.max, Time.getFormatTimezone())
122
138
  })
123
139
 
124
140
  // Functions
@@ -165,8 +181,8 @@ function toHMS (value) {
165
181
  }
166
182
  }
167
183
 
168
- // Immedaite
169
- if (props.modelValue) dateTime.value = moment.utc(props.modelValue).local()
170
- if (props.min) minDateTime.value = moment.utc(props.min).local()
171
- if (props.max) maxDateTime.value = moment.utc(props.max).local()
184
+ // Immediate
185
+ if (props.modelValue) dateTime.value = toLocalTimezone(props.modelValue, Time.getFormatTimezone())
186
+ if (props.min) minDateTime.value = toLocalTimezone(props.min, Time.getFormatTimezone())
187
+ if (props.max) maxDateTime.value = toLocalTimezone(props.max, Time.getFormatTimezone())
172
188
  </script>