@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.
- package/.travis.test.sh +42 -10
- package/README.md +2 -2
- package/core/api/application.js +6 -1
- package/core/api/authentication.js +17 -1
- package/core/api/db.js +7 -2
- package/core/api/hooks/hooks.authentication.js +4 -2
- package/core/api/hooks/hooks.authorisations.js +12 -2
- package/core/api/hooks/hooks.model.js +5 -5
- package/core/api/hooks/hooks.organisations.js +0 -4
- package/core/api/services/account/account.hooks.js +10 -6
- package/core/api/services/account/account.service.js +1 -1
- package/{map/api/services/geocoder/geocoder.hooks.js → core/api/services/import-export/import-export.hooks.js} +7 -5
- package/core/api/services/import-export/import-export.service.js +11 -0
- package/core/api/services/index.js +13 -1
- package/core/api/services/users/users.hooks.js +2 -3
- package/core/client/api.js +16 -14
- package/core/client/capabilities.js +6 -2
- package/core/client/components/KContent.vue +11 -1
- package/core/client/components/KDialog.vue +17 -15
- package/core/client/components/KSponsor.vue +1 -1
- package/core/client/components/KTextArea.vue +5 -1
- package/core/client/components/app/KAbout.vue +1 -2
- package/core/client/components/app/KWelcome.vue +3 -5
- package/core/client/components/chart/KTimeSeriesChart.vue +24 -37
- package/core/client/components/collection/KColumn.vue +20 -17
- package/core/client/components/editor/KModalEditor.vue +0 -2
- package/core/client/components/form/KChipsField.vue +12 -2
- package/core/client/components/form/KColorField.vue +12 -2
- package/core/client/components/form/KColorScaleField.vue +12 -2
- package/core/client/components/form/KDateTimeRangeField.vue +12 -2
- package/core/client/components/form/KDatetimeField.vue +12 -2
- package/core/client/components/form/KEmailField.vue +12 -2
- package/core/client/components/form/KFileField.vue +12 -2
- package/core/client/components/form/KForm.vue +43 -9
- package/core/client/components/form/KIconField.vue +12 -2
- package/core/client/components/form/KItemField.vue +25 -4
- package/core/client/components/form/KNumberField.vue +12 -2
- package/core/client/components/form/KOptionsField.vue +12 -2
- package/core/client/components/form/KPasswordField.vue +12 -2
- package/core/client/components/form/KPhoneField.vue +13 -3
- package/core/client/components/form/KPropertyItemField.vue +12 -2
- package/core/client/components/form/KResolutionField.vue +126 -0
- package/core/client/components/form/KRoleField.vue +12 -2
- package/core/client/components/form/KSelectField.vue +14 -4
- package/core/client/components/form/KTextField.vue +12 -2
- package/core/client/components/form/KTextareaField.vue +13 -3
- package/core/client/components/form/KToggleField.vue +12 -2
- package/core/client/components/form/KTokenField.vue +12 -2
- package/core/client/components/form/KUnitField.vue +12 -2
- package/core/client/components/form/KUrlField.vue +12 -2
- package/core/client/components/input/KIconChooser.vue +10 -12
- package/core/client/components/input/KPalette.vue +2 -1
- package/core/client/components/layout/KPage.vue +5 -4
- package/core/client/components/layout/KWindow.vue +10 -10
- package/core/client/components/media/KColorScale.vue +26 -20
- package/core/client/components/media/KImageViewer.vue +57 -33
- package/core/client/components/media/KShape.vue +14 -103
- package/core/client/components/screen/KRegisterScreen.vue +0 -1
- package/core/client/components/screen/KScreenFooter.vue +0 -18
- package/core/client/components/team/KAddMember.vue +16 -22
- package/core/client/components/team/KGroupsActivity.vue +14 -0
- package/core/client/components/team/KMembersActivity.vue +12 -0
- package/core/client/components/team/KTagsActivity.vue +14 -0
- package/core/client/components/time/KDateTime.vue +23 -7
- package/core/client/components/time/KTimeControl.vue +142 -0
- package/core/client/components/tool/KExportTool.vue +57 -0
- package/core/client/composables/collection.js +0 -1
- package/core/client/composables/pwa.js +0 -1
- package/core/client/composables/schema.js +1 -1
- package/core/client/composables/session.js +30 -6
- package/core/client/exporter.js +141 -0
- package/core/client/i18n/core_en.json +91 -23
- package/core/client/i18n/core_fr.json +92 -23
- package/core/client/index.js +3 -0
- package/core/client/layout.js +34 -14
- package/core/client/local-storage.js +8 -6
- package/core/client/mixins/index.js +0 -1
- package/core/client/mixins/mixin.base-field.js +24 -2
- package/core/client/mixins/mixin.object-proxy.js +0 -1
- package/core/client/search.js +2 -1
- package/core/client/services/index.js +2 -1
- package/core/client/services/local-settings.service.js +4 -4
- package/core/client/theme.js +3 -3
- package/core/client/time.js +4 -0
- package/core/client/units.js +149 -4
- package/core/client/utils/index.js +13 -6
- package/core/client/utils/utils.account.js +1 -1
- package/core/client/utils/utils.colors.js +43 -0
- package/core/client/utils/utils.platform.js +0 -1
- package/core/client/utils/utils.pwa.js +14 -14
- package/core/client/utils/utils.session.js +1 -1
- package/core/client/utils/utils.shapes.js +270 -0
- package/core/client/utils/utils.time.js +37 -0
- package/core/common/permissions.js +3 -0
- package/core/common/schemas/settings.update.json +50 -29
- package/extras/css/core.variables.scss +3 -1
- package/extras/tours/map/navigation-bar.js +17 -15
- package/extras/tours/map/timeline.js +33 -33
- package/map/api/config/categories.cjs +4 -1
- package/map/api/hooks/hooks.catalog.js +39 -0
- package/map/api/hooks/hooks.features.js +23 -3
- package/map/api/hooks/hooks.query.js +31 -10
- package/map/api/models/projects.model.mongodb.js +8 -0
- package/map/api/services/catalog/catalog.hooks.js +5 -3
- package/map/api/services/features/features.hooks.js +18 -6
- package/map/api/services/index.js +22 -6
- package/map/api/services/projects/projects.hooks.js +118 -0
- package/map/client/capture.js +16 -0
- package/map/client/cesium/utils/index.js +3 -0
- package/map/client/cesium/utils/utils.events.js +30 -0
- package/map/client/cesium/utils/utils.popup.js +17 -0
- package/map/client/cesium/{utils.js → utils/utils.style.js} +53 -49
- package/map/client/components/KCapture.vue +50 -0
- package/map/client/components/KCaptureTextArea.vue +53 -0
- package/map/client/components/KCompass.vue +2 -2
- package/map/client/components/KFeaturesChart.vue +1 -1
- package/map/client/components/KFeaturesFilter.vue +2 -2
- package/map/client/components/KLayerStyleForm.vue +256 -430
- package/map/client/components/KLevelSlider.vue +1 -1
- package/map/client/components/KNorth.vue +31 -0
- package/map/client/components/KProjectMenu.vue +88 -0
- package/map/client/components/KTimezoneMap.vue +36 -23
- package/map/client/components/catalog/KAddLayer.vue +3 -4
- package/map/client/components/catalog/KConnectLayer.vue +16 -4
- package/map/client/components/catalog/KCreateLayer.vue +1 -2
- package/map/client/components/catalog/KCreateProject.vue +100 -0
- package/map/client/components/catalog/KCreateView.vue +25 -2
- package/map/client/components/catalog/KLayersPanel.vue +24 -27
- package/map/client/components/catalog/KLayersSelector.vue +1 -1
- package/map/client/components/catalog/KProjectEditor.vue +91 -0
- package/map/client/components/catalog/KProjectManager.vue +60 -0
- package/map/client/components/catalog/KProjectSelector.vue +38 -0
- package/map/client/components/catalog/KProjectsPanel.vue +153 -0
- package/map/client/components/catalog/KSelectLayers.vue +96 -0
- package/map/client/components/catalog/KSelectViews.vue +96 -0
- package/map/client/components/catalog/KViewsPanel.vue +66 -30
- package/map/client/components/form/KDirectionField.vue +24 -5
- package/map/client/components/form/KLayerCategoryField.vue +12 -2
- package/map/client/components/form/KLocationField.vue +20 -5
- package/map/client/components/form/KOwsLayerField.vue +12 -2
- package/map/client/components/form/KOwsServiceField.vue +12 -2
- package/map/client/components/form/KSelectLayersField.vue +159 -0
- package/map/client/components/form/KSelectViewsField.vue +121 -0
- package/map/client/components/form/KTimezoneField.vue +24 -17
- package/map/client/components/legend/KColorScaleLegend.vue +1 -1
- package/map/client/components/legend/KLayerLegend.vue +61 -0
- package/map/client/components/legend/KLegend.vue +45 -44
- package/map/client/components/legend/KLegendRenderer.vue +5 -3
- package/map/client/components/legend/KSymbolsLegend.vue +12 -10
- package/map/client/components/legend/KVariablesLegend.vue +78 -0
- package/map/client/components/location/KGeocodersFilter.vue +2 -4
- package/map/client/components/location/KLocationMap.vue +48 -17
- package/map/client/components/location/KLocationSearch.vue +13 -3
- package/map/client/components/tools/KSearchTool.vue +17 -12
- package/map/client/components/widget/KElevationProfile.vue +16 -19
- package/map/client/components/widget/KMapillaryViewer.vue +21 -22
- package/map/client/components/widget/KTimeSeries.vue +35 -23
- package/map/client/composables/activity.js +15 -2
- package/map/client/composables/catalog.js +66 -0
- package/map/client/composables/highlight.js +56 -20
- package/map/client/composables/index.js +2 -0
- package/map/client/composables/location.js +25 -18
- package/map/client/composables/project.js +122 -0
- package/map/client/geolocation.js +1 -1
- package/map/client/globe.js +2 -0
- package/map/client/i18n/map_en.json +123 -76
- package/map/client/i18n/map_fr.json +124 -72
- package/map/client/index.js +3 -0
- package/map/client/init.js +17 -0
- package/map/client/leaflet/GSMaPLayer.js +16 -17
- package/map/client/leaflet/ShapeMarker.js +40 -0
- package/map/client/leaflet/TiledFeatureLayer.js +1 -1
- package/map/client/leaflet/TiledMeshLayer.js +11 -15
- package/map/client/leaflet/TiledWindLayer.js +6 -10
- package/map/client/leaflet/utils/index.js +4 -0
- package/map/client/leaflet/utils/utils.events.js +41 -0
- package/map/client/leaflet/utils/utils.popup.js +21 -0
- package/map/client/leaflet/utils/utils.style.js +191 -0
- package/map/client/leaflet/utils/utils.tiles.js +87 -0
- package/map/client/map.js +2 -0
- package/map/client/mixins/globe/mixin.base-globe.js +29 -21
- package/map/client/mixins/globe/mixin.geojson-layers.js +132 -69
- package/map/client/mixins/globe/mixin.popup.js +2 -1
- package/map/client/mixins/globe/mixin.style.js +6 -4
- package/map/client/mixins/globe/mixin.tooltip.js +8 -3
- package/map/client/mixins/map/mixin.base-map.js +13 -11
- package/map/client/mixins/map/mixin.edit-layers.js +15 -15
- package/map/client/mixins/map/mixin.forecast-layers.js +3 -1
- package/map/client/mixins/map/mixin.geojson-layers.js +56 -20
- package/map/client/mixins/map/mixin.georaster-layers.js +4 -11
- package/map/client/mixins/map/mixin.heatmap-layers.js +1 -1
- package/map/client/mixins/map/mixin.popup.js +2 -1
- package/map/client/mixins/map/mixin.style.js +4 -67
- package/map/client/mixins/map/mixin.tiled-mesh-layers.js +2 -1
- package/map/client/mixins/map/mixin.tiled-wind-layers.js +4 -2
- package/map/client/mixins/map/mixin.tooltip.js +2 -1
- package/map/client/mixins/mixin.activity.js +66 -191
- package/map/client/mixins/mixin.catalog-panel.js +6 -6
- package/map/client/mixins/mixin.context.js +12 -9
- package/map/client/mixins/mixin.feature-service.js +29 -300
- package/map/client/mixins/mixin.weacast.js +11 -17
- package/map/client/pixi-utils.js +1 -1
- package/map/client/planets.js +58 -0
- package/map/client/utils/index.js +6 -0
- package/map/client/utils/utils.capture.js +176 -0
- package/map/client/utils/utils.catalog.js +149 -0
- package/map/client/utils/utils.features.js +364 -0
- package/map/client/utils/utils.js +0 -151
- package/map/client/utils/utils.layers.js +174 -0
- package/map/client/utils/utils.location.js +91 -23
- package/map/client/utils/utils.project.js +8 -0
- package/map/client/utils/utils.schema.js +0 -1
- package/map/client/utils/utils.style.js +297 -0
- package/map/client/utils.all.js +2 -2
- package/map/client/utils.globe.js +1 -1
- package/map/client/utils.map.js +1 -1
- package/map/common/permissions.js +2 -0
- package/map/common/schemas/capture.create.json +132 -0
- package/map/common/schemas/projects.create.json +52 -0
- package/map/common/schemas/projects.update.json +52 -0
- package/package.json +6 -5
- package/test/api/core/account.test.js +20 -0
- package/test/api/core/config/default.cjs +16 -3
- package/test/api/core/import-export.test.js +86 -0
- package/test/api/core/test-log-2024-01-04.log +14 -0
- package/test/api/map/catalog.test.js +164 -0
- package/test/api/map/index.test.js +25 -61
- package/test/api/map/test-log-2024-01-04.log +2 -0
- package/test/api/map/test-log-2024-01-11.log +1 -0
- package/test/api/map/test-log-2024-01-25.log +19 -0
- package/test/client/core/layout.js +25 -5
- package/test/client/core/utils.js +7 -0
- package/test/client/map/catalog.js +78 -1
- package/test/client/map/time.js +2 -1
- package/core/client/components/screen/KEndpointScreen.vue +0 -80
- package/core/client/mixins/mixin.account.js +0 -61
- package/extras/icons/kdk.png +0 -0
- package/map/api/services/geocoder/geocoder.service.js +0 -79
- package/map/client/components/KCaptureToolbar.vue +0 -155
- package/map/client/components/KColorLegend.vue +0 -349
- package/map/client/components/KTimeline.vue +0 -293
- package/map/client/components/KUrlLegend.vue +0 -122
- package/map/client/leaflet/utils.js +0 -246
package/core/client/units.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
|
+
import logger from 'loglevel'
|
|
2
3
|
import * as math from 'mathjs'
|
|
3
4
|
import config from 'config'
|
|
4
5
|
import { i18n } from './i18n.js'
|
|
@@ -93,6 +94,106 @@ const angle = {
|
|
|
93
94
|
label: 'units.RADIAN_LABEL'
|
|
94
95
|
}
|
|
95
96
|
}
|
|
97
|
+
const fraction = {
|
|
98
|
+
ppm: {
|
|
99
|
+
symbol: 'units.PPM_SYMBOL',
|
|
100
|
+
label: 'units.PPM_LABEL'
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const density = {
|
|
104
|
+
'ug/m^3': {
|
|
105
|
+
symbol: 'units.MICROGRAM_PER_M3_SYMBOL',
|
|
106
|
+
label: 'units.MICROGRAM_PER_M3_LABEL'
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const volumeVelocity = {
|
|
110
|
+
'm^3/s': {
|
|
111
|
+
symbol: 'units.CUBIC_METER_PER_SECOND_SYMBOL',
|
|
112
|
+
label: 'units.CUBIC_METER_PER_SECOND_LABEL'
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const radioactivity = {
|
|
116
|
+
bq: {
|
|
117
|
+
symbol: 'units.BEQUEREL_SYMBOL',
|
|
118
|
+
label: 'units.BEQUEREL_LABEL',
|
|
119
|
+
baseName: 'radioactivity'
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const radioactivityDensity = {
|
|
123
|
+
'bq/m^2': {
|
|
124
|
+
symbol: 'units.BEQUEREL_PER_M2_SYMBOL',
|
|
125
|
+
label: 'units.BEQUEREL_PER_M2_LABEL'
|
|
126
|
+
},
|
|
127
|
+
'bq/m^3': {
|
|
128
|
+
symbol: 'units.BEQUEREL_PER_M3_SYMBOL',
|
|
129
|
+
label: 'units.BEQUEREL_PER_M3_LABEL'
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const equivalentDose = {
|
|
133
|
+
sv: {
|
|
134
|
+
symbol: 'units.SIEVERT_SYMBOL',
|
|
135
|
+
label: 'units.SIEVERT_LABEL',
|
|
136
|
+
baseName: 'equivalentDose',
|
|
137
|
+
aliases: ['sievert']
|
|
138
|
+
},
|
|
139
|
+
msv: {
|
|
140
|
+
symbol: 'units.MILLISIEVERT_SYMBOL',
|
|
141
|
+
label: 'units.MILLISIEVERT_LABEL',
|
|
142
|
+
definition: '0.001 sv'
|
|
143
|
+
},
|
|
144
|
+
usv: {
|
|
145
|
+
symbol: 'units.MICROSIEVERT_SYMBOL',
|
|
146
|
+
label: 'units.MICROSIEVERT_LABEL',
|
|
147
|
+
definition: '0.000001 sv'
|
|
148
|
+
},
|
|
149
|
+
nsv: {
|
|
150
|
+
symbol: 'units.NANOSIEVERT_SYMBOL',
|
|
151
|
+
label: 'units.NANOSIEVERT_LABEL',
|
|
152
|
+
definition: '0.000000001 sv'
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const equivalentDoseRate = {
|
|
156
|
+
svs: {
|
|
157
|
+
symbol: 'units.SIEVERT_PER_SECOND_SYMBOL',
|
|
158
|
+
label: 'units.SIEVERT_PER_SECOND_LABEL',
|
|
159
|
+
baseName: 'equivalentDoseRate'
|
|
160
|
+
},
|
|
161
|
+
msvs: {
|
|
162
|
+
symbol: 'units.MILLISIEVERT_PER_SECOND_SYMBOL',
|
|
163
|
+
label: 'units.MILLISIEVERT_PER_SECOND_LABEL',
|
|
164
|
+
definition: '0.001 svs'
|
|
165
|
+
},
|
|
166
|
+
usvs: {
|
|
167
|
+
symbol: 'units.MICROSIEVERT_PER_SECOND_SYMBOL',
|
|
168
|
+
label: 'units.MICROSIEVERT_PER_SECOND_LABEL',
|
|
169
|
+
definition: '0.000001 svs'
|
|
170
|
+
},
|
|
171
|
+
nsvs: {
|
|
172
|
+
symbol: 'units.NANOSIEVERT_PER_SECOND_SYMBOL',
|
|
173
|
+
label: 'units.NANOSIEVERT_PER_SECOND_LABEL',
|
|
174
|
+
definition: '0.000000001 svs'
|
|
175
|
+
},
|
|
176
|
+
svh: {
|
|
177
|
+
symbol: 'units.SIEVERT_PER_HOUR_SYMBOL',
|
|
178
|
+
label: 'units.SIEVERT_PER_HOUR_LABEL',
|
|
179
|
+
definition: '0.000277778 svs'
|
|
180
|
+
},
|
|
181
|
+
msvh: {
|
|
182
|
+
symbol: 'units.MILLISIEVERT_PER_HOUR_SYMBOL',
|
|
183
|
+
label: 'units.MILLISIEVERT_PER_HOUR_LABEL',
|
|
184
|
+
definition: '0.000000277778 svs'
|
|
185
|
+
},
|
|
186
|
+
usvh: {
|
|
187
|
+
symbol: 'units.MICROSIEVERT_PER_HOUR_SYMBOL',
|
|
188
|
+
label: 'units.MICROSIEVERT_PER_HOUR_LABEL',
|
|
189
|
+
definition: '0.000000000277778 svs'
|
|
190
|
+
},
|
|
191
|
+
nsvh: {
|
|
192
|
+
symbol: 'units.NANOSIEVERT_PER_HOUR_SYMBOL',
|
|
193
|
+
label: 'units.NANOSIEVERT_PER_HOUR_LABEL',
|
|
194
|
+
definition: '0.000000000000277778 svs'
|
|
195
|
+
}
|
|
196
|
+
}
|
|
96
197
|
|
|
97
198
|
const quantities = {
|
|
98
199
|
length,
|
|
@@ -100,7 +201,14 @@ const quantities = {
|
|
|
100
201
|
area,
|
|
101
202
|
velocity,
|
|
102
203
|
temperature,
|
|
103
|
-
angle
|
|
204
|
+
angle,
|
|
205
|
+
fraction,
|
|
206
|
+
density,
|
|
207
|
+
volumeVelocity,
|
|
208
|
+
radioactivity,
|
|
209
|
+
radioactivityDensity,
|
|
210
|
+
equivalentDose,
|
|
211
|
+
equivalentDoseRate
|
|
104
212
|
}
|
|
105
213
|
|
|
106
214
|
// Export singleton
|
|
@@ -116,6 +224,9 @@ export const Units = {
|
|
|
116
224
|
velocity: 'm/s',
|
|
117
225
|
temperature: 'degC',
|
|
118
226
|
angle: 'deg',
|
|
227
|
+
radioactivity: 'bq',
|
|
228
|
+
equivalentDose: 'usv',
|
|
229
|
+
equivalentDoseRate: 'usvh',
|
|
119
230
|
notation: 'auto',
|
|
120
231
|
precision: 3
|
|
121
232
|
}
|
|
@@ -171,33 +282,67 @@ export const Units = {
|
|
|
171
282
|
return units
|
|
172
283
|
}
|
|
173
284
|
},
|
|
285
|
+
// Get unit definition by name
|
|
174
286
|
getUnit (unit) {
|
|
175
287
|
return _.find(this.getUnits(), { name: unit })
|
|
176
288
|
},
|
|
289
|
+
// Get unit symbol by unit name
|
|
177
290
|
getUnitSymbol (unit) {
|
|
178
291
|
const definition = this.getUnit(unit)
|
|
179
292
|
return (definition ? i18n.t(definition.symbol) : unit)
|
|
180
293
|
},
|
|
294
|
+
// Get default unit definition (if any) for a given quantity/unit name
|
|
181
295
|
getDefaultUnit (quantityOrUnit) {
|
|
182
296
|
// Check for quantity first
|
|
183
297
|
let defaultUnit = Store.get(`units.default.${quantityOrUnit}`)
|
|
184
298
|
// If not check by matching quantity based on given unit
|
|
185
299
|
if (!defaultUnit) {
|
|
186
|
-
const baseUnit =
|
|
300
|
+
const baseUnit = this.getUnit(quantityOrUnit)
|
|
187
301
|
// Get default unit for this quantity instead
|
|
188
|
-
if (baseUnit) defaultUnit =
|
|
302
|
+
if (baseUnit) defaultUnit = this.getDefaultUnit(baseUnit.quantity)
|
|
189
303
|
}
|
|
190
304
|
return defaultUnit
|
|
191
305
|
},
|
|
306
|
+
// Get symbol of default unit (if any) for a given quantity/unit name
|
|
307
|
+
getDefaultUnitSymbol (quantityOrUnit) {
|
|
308
|
+
return this.getUnitSymbol(this.getDefaultUnit(quantityOrUnit))
|
|
309
|
+
},
|
|
310
|
+
// Get target unit for a source unit, will be default unit (if any) or source unit
|
|
311
|
+
getTargetUnit (sourceUnit) {
|
|
312
|
+
return this.getDefaultUnit(sourceUnit) || sourceUnit
|
|
313
|
+
},
|
|
314
|
+
// Get target unit symbol for a source unit, will be default unit symbol (if any) or source unit symbol
|
|
315
|
+
getTargetUnitSymbol (sourceUnit) {
|
|
316
|
+
return this.getUnitSymbol(this.getTargetUnit(sourceUnit))
|
|
317
|
+
},
|
|
318
|
+
// Convert between units by names
|
|
319
|
+
// If target unit is not specified will use default unit (if any) for source unit
|
|
192
320
|
convert (value, sourceUnit, targetUnit) {
|
|
193
|
-
if (
|
|
321
|
+
if (_.isNil(value)) {
|
|
322
|
+
logger.warn(`[KDK] cannont convert an nil value`)
|
|
323
|
+
return
|
|
324
|
+
}
|
|
325
|
+
if (value === Number.MIN_VALUE || value === Number.MAX_VALUE) return value
|
|
326
|
+
// If target unit is not given use default one
|
|
327
|
+
if (!targetUnit) targetUnit = this.getDefaultUnit(sourceUnit)
|
|
328
|
+
// Check if the target unit does exist
|
|
329
|
+
if (!targetUnit) return value
|
|
330
|
+
// Check if the source unit does exist
|
|
331
|
+
if (!math.Unit.isValuelessUnit(sourceUnit)) return value
|
|
194
332
|
let n = math.unit(value, sourceUnit)
|
|
195
333
|
n = n.toNumber(targetUnit)
|
|
196
334
|
// Remap from [-180,+180[ to [0,360[ for angles
|
|
197
335
|
n = (targetUnit === 'deg' ? (n < 0.0 ? n + 360.0 : n) : n)
|
|
198
336
|
return n
|
|
199
337
|
},
|
|
338
|
+
// Format display of source value in target unit, converting from source unit
|
|
339
|
+
// If target unit is not specified will use default unit (if any) for source unit
|
|
340
|
+
// options are mathjs format options
|
|
200
341
|
format (value, sourceUnit, targetUnit, options) {
|
|
342
|
+
if (_.isNil(value)) {
|
|
343
|
+
logger.warn(`[KDK] cannot format a nil value`)
|
|
344
|
+
return
|
|
345
|
+
}
|
|
201
346
|
// If target unit is not given use default one
|
|
202
347
|
if (!targetUnit) targetUnit = this.getDefaultUnit(sourceUnit)
|
|
203
348
|
const n = (targetUnit ? this.convert(value, sourceUnit, targetUnit) : value)
|
|
@@ -12,7 +12,9 @@ export * from './utils.locale.js'
|
|
|
12
12
|
export * from './utils.platform.js'
|
|
13
13
|
export * from './utils.push.js'
|
|
14
14
|
export * from './utils.pwa.js'
|
|
15
|
+
export * from './utils.shapes.js'
|
|
15
16
|
export * from './utils.session.js'
|
|
17
|
+
export * from './utils.time.js'
|
|
16
18
|
|
|
17
19
|
Notify.setDefaults({
|
|
18
20
|
position: 'bottom-left',
|
|
@@ -107,6 +109,17 @@ export function dataUriToBlob (dataUri) {
|
|
|
107
109
|
return new Blob([ab], { type: mimeType })
|
|
108
110
|
}
|
|
109
111
|
|
|
112
|
+
// Taken from https://github.com/juanelas/base64
|
|
113
|
+
export const base64Encode = function (bytes) {
|
|
114
|
+
bytes = new Uint8Array(bytes)
|
|
115
|
+
const CHUNK_SIZE = 0x8000
|
|
116
|
+
const array = []
|
|
117
|
+
for (let i = 0; i < bytes.length; i += CHUNK_SIZE) {
|
|
118
|
+
array.push(String.fromCharCode.apply(null, bytes.subarray(i, i + CHUNK_SIZE)))
|
|
119
|
+
}
|
|
120
|
+
return btoa(array.join(''))
|
|
121
|
+
}
|
|
122
|
+
|
|
110
123
|
export function downloadAsBlob (data, filename, mimeType) {
|
|
111
124
|
const blob = new Blob([data], { type: mimeType })
|
|
112
125
|
exportFile(filename, blob)
|
|
@@ -174,12 +187,6 @@ export function isObjectID (id) {
|
|
|
174
187
|
return (id.length === 24 && checkForHexRegExp.test(id))
|
|
175
188
|
}
|
|
176
189
|
|
|
177
|
-
// Add UTC offset to timezone name
|
|
178
|
-
export function getTimezoneLabel (timezone) {
|
|
179
|
-
const offset = moment().tz(timezone).format('Z')
|
|
180
|
-
return `${timezone} (${offset})`
|
|
181
|
-
}
|
|
182
|
-
|
|
183
190
|
// Helper function to load a schema
|
|
184
191
|
// @schema alias shoud be added in the quasar.config build section
|
|
185
192
|
export async function loadSchema (schemaName) {
|
|
@@ -2,7 +2,7 @@ import { api } from '../api.js'
|
|
|
2
2
|
|
|
3
3
|
export async function verifyEmail (email) {
|
|
4
4
|
const response = await api.getService('account').verifyEmail({ email })
|
|
5
|
-
return response.status === 200
|
|
5
|
+
return response.status === 200
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export function resendVerifySignup (email) {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
|
+
import logger from 'loglevel'
|
|
3
|
+
import { getCssVar } from 'quasar'
|
|
4
|
+
import chroma from 'chroma-js'
|
|
2
5
|
|
|
3
6
|
export const Colors = {
|
|
7
|
+
white: '#fff',
|
|
4
8
|
dark: '#333',
|
|
5
9
|
red: '#f44336',
|
|
6
10
|
pink: '#e91e63',
|
|
@@ -23,6 +27,11 @@ export const Colors = {
|
|
|
23
27
|
'blue-grey': '#607d8b'
|
|
24
28
|
}
|
|
25
29
|
|
|
30
|
+
export function getHtmlColor (color, defaultColor) {
|
|
31
|
+
if (!color) return defaultColor
|
|
32
|
+
return getCssVar(color) || color
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
export function getPaletteFromColor (color) {
|
|
27
36
|
// Check if already a color of the palette
|
|
28
37
|
if (Colors[color]) return color
|
|
@@ -34,3 +43,37 @@ export function getColorFromPalette (color) {
|
|
|
34
43
|
if (color.startsWith('#')) return color
|
|
35
44
|
else return Colors[color] || '#ffffff'
|
|
36
45
|
}
|
|
46
|
+
|
|
47
|
+
export function buildColorScale (options) {
|
|
48
|
+
if (!options) {
|
|
49
|
+
logger.warn(`[KDK] buildColorScale: 'options' argument must be defined`)
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
let colors = options.colors
|
|
53
|
+
if (!colors) {
|
|
54
|
+
// For backward compatibility
|
|
55
|
+
if (options.scale) {
|
|
56
|
+
logger.warn(`[KDK] buildColorScale: please update 'scale' property to 'colors'`)
|
|
57
|
+
colors = options.scale
|
|
58
|
+
} else {
|
|
59
|
+
logger.warn(`[KDK] buildColorScale: no colors defined, using default default colors 'Spectral'`)
|
|
60
|
+
colors = 'Spectral'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
let scale = chroma.scale(colors)
|
|
64
|
+
if (options.classes) {
|
|
65
|
+
if (Array.isArray(options.classes)) {
|
|
66
|
+
// The provided classes implicitly define the domain, then we omit the domain
|
|
67
|
+
scale = scale.classes(options.classes)
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
// In this case, we need to take into account an optional domain
|
|
71
|
+
if (options.domain) scale = scale.domain(options.domain).classes(options.classes)
|
|
72
|
+
else scale = scale.classes(options.classes)
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
// No classes defined, we need to take into account an optional domain
|
|
76
|
+
if (options.domain) scale = scale.domain(options.domain)
|
|
77
|
+
}
|
|
78
|
+
return scale
|
|
79
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Dialog } from 'quasar'
|
|
2
2
|
import { i18n } from '../i18n.js'
|
|
3
3
|
|
|
4
4
|
export let InstallPwaPrompt = null
|
|
@@ -6,22 +6,22 @@ export let InstallPwaPrompt = null
|
|
|
6
6
|
window.addEventListener('beforeinstallprompt', (e) => {
|
|
7
7
|
e.preventDefault()
|
|
8
8
|
// Stash the event so it can be triggered later
|
|
9
|
-
InstallPwaPrompt = e
|
|
9
|
+
InstallPwaPrompt = e
|
|
10
10
|
})
|
|
11
11
|
|
|
12
12
|
export function installDefaultPrompt () {
|
|
13
|
-
|
|
14
|
-
title: i18n.t('
|
|
15
|
-
message: i18n.t('
|
|
13
|
+
Dialog.create({
|
|
14
|
+
title: i18n.t('utils.pwa.INSTALL_TITLE'),
|
|
15
|
+
message: i18n.t('utils.pwa.INSTALL_MESSAGE'),
|
|
16
16
|
cancel: {
|
|
17
17
|
id: 'ignore-button',
|
|
18
|
-
label: i18n.t('
|
|
18
|
+
label: i18n.t('utils.pwa.IGNORE'),
|
|
19
19
|
color: 'primary',
|
|
20
20
|
outline: true
|
|
21
21
|
},
|
|
22
22
|
ok: {
|
|
23
23
|
id: 'install-button',
|
|
24
|
-
label: i18n.t('
|
|
24
|
+
label: i18n.t('utils.pwa.INSTALL'),
|
|
25
25
|
color: 'primary'
|
|
26
26
|
},
|
|
27
27
|
persistent: true,
|
|
@@ -37,9 +37,9 @@ export function installDefaultPrompt () {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export function installSafariPrompt () {
|
|
40
|
-
|
|
41
|
-
title: i18n.t('
|
|
42
|
-
message: i18n.t('
|
|
40
|
+
Dialog.create({
|
|
41
|
+
title: i18n.t('utils.pwa.INSTALL_TITLE'),
|
|
42
|
+
message: i18n.t('utils.pwa.IOS_INSTALL_MESSAGE'),
|
|
43
43
|
ok: {
|
|
44
44
|
color: 'primary'
|
|
45
45
|
},
|
|
@@ -50,9 +50,9 @@ export function installSafariPrompt () {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export function installFFDesktopPrompt () {
|
|
53
|
-
|
|
54
|
-
title: i18n.t('
|
|
55
|
-
message: i18n.t('
|
|
53
|
+
Dialog.create({
|
|
54
|
+
title: i18n.t('utils.pwa.INSTALL_TITLE'),
|
|
55
|
+
message: i18n.t('utils.pwa.FIREFOX_DESKTOP_INSTALL_MESSAGE'),
|
|
56
56
|
ok: {
|
|
57
57
|
color: 'primary'
|
|
58
58
|
},
|
|
@@ -60,4 +60,4 @@ export function installFFDesktopPrompt () {
|
|
|
60
60
|
position: 'bottom',
|
|
61
61
|
html: true
|
|
62
62
|
})
|
|
63
|
-
}
|
|
63
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
1
2
|
import logger from 'debug'
|
|
2
3
|
import { Store } from '../store.js'
|
|
3
4
|
import { api } from '../api.js'
|
|
@@ -34,7 +35,6 @@ export async function logout () {
|
|
|
34
35
|
// Rethrow for caller to handle
|
|
35
36
|
throw error
|
|
36
37
|
}
|
|
37
|
-
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export async function restoreSession () {
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
2
|
+
import logger from 'loglevel'
|
|
3
|
+
import { uid } from 'quasar'
|
|
4
|
+
import { getHtmlColor } from './utils.colors.js'
|
|
5
|
+
|
|
6
|
+
const defaultSize = { width: 24, height: 24 }
|
|
7
|
+
const defaultColor = 'black'
|
|
8
|
+
const defaultIconSize = 12
|
|
9
|
+
const defaultTextSize = 12
|
|
10
|
+
|
|
11
|
+
function defaultRadiusToSize (r) {
|
|
12
|
+
return { width: r * 2, height: r * 2 }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Predefined shapes
|
|
16
|
+
// see https://www.svgrepo.com/ to look for a shape
|
|
17
|
+
export const Shapes = {
|
|
18
|
+
circle: {
|
|
19
|
+
viewBox: [0, 0, 100, 100],
|
|
20
|
+
content: '<circle cx="50" cy="50" r="50" />'
|
|
21
|
+
},
|
|
22
|
+
rect: {
|
|
23
|
+
viewBox: [0, 0, 100, 100],
|
|
24
|
+
content: '<rect cx="0" cy="0" width="100" height="100" />',
|
|
25
|
+
radiusToSize: (r) => { return { width: Math.round(r * 2 * 0.9), height: Math.round(r * 2 * 0.9) } }
|
|
26
|
+
},
|
|
27
|
+
'rounded-rect': {
|
|
28
|
+
viewBox: [0, 0, 100, 100],
|
|
29
|
+
content: '<rect cx="0" cy="0" width="100" height="100" rx="20" ry="20" />',
|
|
30
|
+
radiusToSize: (r) => { return { width: Math.round(r * 2 * 0.9), height: Math.round(r * 2 * 0.9) } }
|
|
31
|
+
},
|
|
32
|
+
diamond: {
|
|
33
|
+
viewBox: [0, 0, 100, 100],
|
|
34
|
+
content: '<polygon points="50 0, 100 50, 50 100, 0 50" />',
|
|
35
|
+
radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.2), height: Math.round(r * 2 * 1.2) } }
|
|
36
|
+
},
|
|
37
|
+
triangle: {
|
|
38
|
+
viewBox: [0, 0, 100, 100],
|
|
39
|
+
content: '<polygon points="50 0, 100 100, 0 100" />',
|
|
40
|
+
radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.125), height: Math.round(r * 2 * 1.025) } }
|
|
41
|
+
},
|
|
42
|
+
'triangle-down': {
|
|
43
|
+
viewBox: [0, 0, 100, 100],
|
|
44
|
+
content: '<polygon points="0 0, 100 0, 50 100" />',
|
|
45
|
+
radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.125), height: Math.round(r * 2 * 1.025) } }
|
|
46
|
+
},
|
|
47
|
+
'triangle-left': {
|
|
48
|
+
viewBox: [0, 0, 100, 100],
|
|
49
|
+
content: '<polygon points="0 50, 100 0, 100 100" />',
|
|
50
|
+
radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.025), height: Math.round(r * 2 * 1.125) } }
|
|
51
|
+
},
|
|
52
|
+
'triangle-right': {
|
|
53
|
+
viewBox: [0, 0, 100, 100],
|
|
54
|
+
content: '<polygon points="0 0, 100 50, 0 100" />',
|
|
55
|
+
radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.025), height: Math.round(r * 2 * 1.125) } }
|
|
56
|
+
},
|
|
57
|
+
star: {
|
|
58
|
+
viewBox: [0, 0, 48, 48],
|
|
59
|
+
content: '<path d="m24,1 6,17h18l-14,11 5,17-15-10-15,10 5-17-14-11h18z" />',
|
|
60
|
+
radiusToSize: (r) => { return { width: Math.round(r * 2 * 1.4), height: Math.round(r * 2 * 1.4) } }
|
|
61
|
+
},
|
|
62
|
+
'marker-pin': {
|
|
63
|
+
viewBox: [0, 0, 384, 512],
|
|
64
|
+
content: '<path d="M384 192c0 87.4-117 243-168.3 307.2c-12.3 15.3-35.1 15.3-47.4 0C117 435 0 279.4 0 192C0 86 86 0 192 0s192 86 192 192z" />',
|
|
65
|
+
icon: {
|
|
66
|
+
translation: ['-50%', '-70%']
|
|
67
|
+
},
|
|
68
|
+
text: {
|
|
69
|
+
translation: ['-50%', '-70%']
|
|
70
|
+
},
|
|
71
|
+
anchor: 'bottom-center'
|
|
72
|
+
},
|
|
73
|
+
'square-pin': {
|
|
74
|
+
viewBox: [0, 0, 56, 56],
|
|
75
|
+
content: '<path d="M 27.9532 52.3633 C 29.0079 52.3633 29.9923 51.9180 30.9298 50.3008 L 35.2657 43.0586 L 43.0938 43.0586 C 50.0783 43.0586 53.8280 39.1914 53.8280 32.3242 L 53.8280 14.3711 C 53.8280 7.5039 50.0783 3.6367 43.0938 3.6367 L 12.9064 3.6367 C 5.9454 3.6367 2.1720 7.4805 2.1720 14.3711 L 2.1720 32.3242 C 2.1720 39.2148 5.9454 43.0586 12.9064 43.0586 L 20.6407 43.0586 L 24.9766 50.3008 C 25.9142 51.9180 26.8985 52.3633 27.9532 52.3633 Z"/>',
|
|
76
|
+
icon: {
|
|
77
|
+
translation: ['-50%', '-75%']
|
|
78
|
+
},
|
|
79
|
+
text: {
|
|
80
|
+
translation: ['-50%', '-60%']
|
|
81
|
+
},
|
|
82
|
+
anchor: 'bottom-center'
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/*
|
|
87
|
+
Helper functions
|
|
88
|
+
*/
|
|
89
|
+
function addTagAttribute (tag, attibute, value) {
|
|
90
|
+
return tag.slice(0, -1) + ` ${attibute}="${value}">`
|
|
91
|
+
}
|
|
92
|
+
function addSvgAttribute (svg, attibute, value) {
|
|
93
|
+
return svg.slice(0, -2) + ` ${attibute}="${value}" />`
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function getSize (size) {
|
|
97
|
+
if (!Array.isArray(size)) return { width: size, height: size }
|
|
98
|
+
return { width: size[0], height: size[1] }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
Utility to create a shape with the following options:
|
|
103
|
+
- shape: String | Object - name of the predefined shape or object specifyinfg the viewBox and the content
|
|
104
|
+
- size : Array - [width, height] of the maker
|
|
105
|
+
- radius: Number - the radius to compute a "visual" size. If the size is defined, the radius is omitted.
|
|
106
|
+
- color: String - the fill color
|
|
107
|
+
- opacity: Number - the fill opacity
|
|
108
|
+
- stroke: Object specifying the stroke properties
|
|
109
|
+
- color: String - the stroke color
|
|
110
|
+
- width: Number - the stroke width - 0
|
|
111
|
+
- opacity: Number - the stroke opacity - 1
|
|
112
|
+
- cap: String - the stroke linecap - 'butt'
|
|
113
|
+
- join: String - the stroke linejoin - 'miter'
|
|
114
|
+
- dashArray: String - the stroke dasharray - 'none'
|
|
115
|
+
- dashOffset: Number - the stroke dashoffset - 0
|
|
116
|
+
- icon: Object specifying an icon overlay
|
|
117
|
+
- classes: String - the icon class
|
|
118
|
+
- url: String - the icon url
|
|
119
|
+
- color: String - the icon color
|
|
120
|
+
- opacity: Number - the icon opacity
|
|
121
|
+
- size: Number - the icon size in pixel - 14
|
|
122
|
+
- translation: Array - the translation to apply from the center of the shape ['-50%', '-50%']
|
|
123
|
+
- rotation: Number - the rotation to apply in degree
|
|
124
|
+
- text: Object specifying a text overlay
|
|
125
|
+
- label: String - the label to display
|
|
126
|
+
- classes: extra classes to apply to the text
|
|
127
|
+
- color: String - the text color
|
|
128
|
+
- size: Number - the font size in pixel - 14
|
|
129
|
+
- translation: Array - the translation to apply from the center of the shape ['-50%', '-50%']
|
|
130
|
+
- rotation: Number - the rotation to apply in degree
|
|
131
|
+
- html: Object specifyinng an html overlay
|
|
132
|
+
|
|
133
|
+
*/
|
|
134
|
+
export function createShape (options) {
|
|
135
|
+
// Check arguments
|
|
136
|
+
if (!options) {
|
|
137
|
+
logger.warn(`[KDK] 'options' argument is required`)
|
|
138
|
+
return
|
|
139
|
+
}
|
|
140
|
+
// Define the anchor
|
|
141
|
+
let anchor = 'middle-center'
|
|
142
|
+
// Define the shape
|
|
143
|
+
let shape
|
|
144
|
+
if (options.shape && options.shape !== 'none') {
|
|
145
|
+
if (typeof options.shape === 'object') shape = options.shape
|
|
146
|
+
else {
|
|
147
|
+
shape = Shapes[options.shape]
|
|
148
|
+
if (!shape) {
|
|
149
|
+
logger.warn(`[KDK] unknown shape '${options.shape}'. Using default shape 'circle'`)
|
|
150
|
+
shape = Shapes['circle']
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
anchor = shape.anchor || anchor
|
|
154
|
+
}
|
|
155
|
+
// Define the size
|
|
156
|
+
let size = defaultSize
|
|
157
|
+
if (options.size) {
|
|
158
|
+
size = getSize(options.size)
|
|
159
|
+
} else {
|
|
160
|
+
if (options.radius) {
|
|
161
|
+
const radiusToSize = _.get(shape, 'radiusToSize', defaultRadiusToSize)
|
|
162
|
+
size = radiusToSize(options.radius)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Set div container vars
|
|
166
|
+
const beginDivTag = `<div style="position: relative; width: ${size.width}px; height: ${size.height}px;">`
|
|
167
|
+
const endDivTag = '</div>'
|
|
168
|
+
// Render shape
|
|
169
|
+
let beginSvgTag = ''
|
|
170
|
+
let svgShapeContent = ''
|
|
171
|
+
let svgClipPath = ''
|
|
172
|
+
let endSvgTag = ''
|
|
173
|
+
if (shape) {
|
|
174
|
+
beginSvgTag = `<svg xmlns="http://www.w3.org/2000/svg" width="${size.width}" height="${size.height}" preserveAspectRatio="none">`
|
|
175
|
+
beginSvgTag = addTagAttribute(beginSvgTag, 'viewBox', _.join(shape.viewBox, ' '))
|
|
176
|
+
svgShapeContent = shape.content
|
|
177
|
+
svgClipPath = ''
|
|
178
|
+
endSvgTag = '</svg>'
|
|
179
|
+
// Apply fill style
|
|
180
|
+
const color = getHtmlColor(options.color, defaultColor)
|
|
181
|
+
svgShapeContent = addSvgAttribute(svgShapeContent, 'fill', color)
|
|
182
|
+
if (options.opacity) svgShapeContent = addSvgAttribute(svgShapeContent, 'fill-opacity', options.opacity)
|
|
183
|
+
// Aply stroke style
|
|
184
|
+
if (options.stroke) {
|
|
185
|
+
// Ensure the stroke color is defined and not transparent
|
|
186
|
+
const strokeColor = getHtmlColor(options.stroke.color, defaultColor)
|
|
187
|
+
if (strokeColor !== 'transparent') {
|
|
188
|
+
svgShapeContent = addSvgAttribute(svgShapeContent, 'stroke', strokeColor)
|
|
189
|
+
// draw inner stroke by double the width and clip the shape by itself
|
|
190
|
+
// see https://stackoverflow.com/questions/7241393/can-you-control-how-an-svgs-stroke-width-is-drawn
|
|
191
|
+
const strokeWidth = options.stroke.width || 1
|
|
192
|
+
svgShapeContent = addSvgAttribute(svgShapeContent, 'stroke-width', strokeWidth * 2)
|
|
193
|
+
// prevent scaling stroke
|
|
194
|
+
svgShapeContent = addSvgAttribute(svgShapeContent, 'vector-effect', 'non-scaling-stroke')
|
|
195
|
+
// additional properties
|
|
196
|
+
if (options.stroke.cap) svgShapeContent = addSvgAttribute(svgShapeContent, 'stroke-linecap', options.stroke.cap)
|
|
197
|
+
if (options.stroke.join) svgShapeContent = addSvgAttribute(svgShapeContent, 'stroke-linejoin', options.stroke.join)
|
|
198
|
+
if (options.stroke.dashArray) svgShapeContent = addSvgAttribute(svgShapeContent, 'stroke-dasharray', options.stroke.dashArray)
|
|
199
|
+
if (options.stroke.dashOffset) svgShapeContent = addSvgAttribute(svgShapeContent, 'stroke-dashoffset', options.stroke.dashOffset)
|
|
200
|
+
const clipId = uid()
|
|
201
|
+
// clip the shape to avoid stroke overflow
|
|
202
|
+
svgShapeContent = addSvgAttribute(svgShapeContent, 'clip-path', `url(#${clipId})`)
|
|
203
|
+
svgClipPath = `<clipPath id="${clipId}">${_.clone(shape.content)}</clipPath>`
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Render icon
|
|
208
|
+
let iconTag = ''
|
|
209
|
+
if (options.icon) {
|
|
210
|
+
if (!_.isNil(options.icon.classes) || !_.isNil(options.icon.url)) {
|
|
211
|
+
if (!_.isEmpty(options.icon.classes) || !_.isEmpty(options.icon.url)) {
|
|
212
|
+
let specificStyle = ''
|
|
213
|
+
if (options.icon.url) {
|
|
214
|
+
let iconSize = options.icon.size ? getSize(options.icon.size) : size
|
|
215
|
+
iconTag = `<img src="${options.icon.url}" `
|
|
216
|
+
// handle size
|
|
217
|
+
iconTag += `width=${iconSize.width} height=${iconSize.height} `
|
|
218
|
+
} else {
|
|
219
|
+
iconTag += `<i class="${options.icon.classes}" `
|
|
220
|
+
// handle color
|
|
221
|
+
const color = getHtmlColor(options.icon.color, defaultColor)
|
|
222
|
+
specificStyle += `color: ${color};`
|
|
223
|
+
// handle size
|
|
224
|
+
let iconSize = options.icon.size || defaultIconSize
|
|
225
|
+
specificStyle += `font-size: ${iconSize}px;`
|
|
226
|
+
}
|
|
227
|
+
const opacity = options.icon.opacity || 1
|
|
228
|
+
const translation = options.icon.translation || _.get(shape, 'icon.translation', ['-50%', '-50%'])
|
|
229
|
+
const rotation = options.icon.rotation || _.get(shape, 'icon.rotation', 0)
|
|
230
|
+
iconTag += `style="position: absolute; top: 50%; left: 50%; transform: translate(${translation[0]},${translation[1]}) rotate(${rotation}deg); opacity: ${opacity}; ${specificStyle}"`
|
|
231
|
+
iconTag += '/>'
|
|
232
|
+
}
|
|
233
|
+
} else {
|
|
234
|
+
logger.warn(`[KDK] icon must contain either the 'classes' property or the 'url' property`)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// Render text
|
|
238
|
+
let textTag = ''
|
|
239
|
+
if (options.text) {
|
|
240
|
+
if (!_.isNil(options.text.label)) {
|
|
241
|
+
if (!_.isEmpty(options.text.label)) {
|
|
242
|
+
textTag = '<span '
|
|
243
|
+
if (options.text.classes) textTag += `classes="${options.text.classes}" `
|
|
244
|
+
const color = getHtmlColor(options.text.color, defaultColor)
|
|
245
|
+
const textSize = options.text.size || defaultTextSize
|
|
246
|
+
const translation = options.text.translation || _.get(shape, 'text.translation', ['-50%', '-50%'])
|
|
247
|
+
const rotation = options.text.rotation || _.get(shape, 'icon.rotation', 0)
|
|
248
|
+
textTag += `style="position: absolute; top: 50%; left: 50%; transform: translate(${translation[0]},${translation[1]}) rotate(${rotation}deg); color: ${color}; font-size: ${textSize}px;"`
|
|
249
|
+
textTag += '>'
|
|
250
|
+
textTag += options.text.label
|
|
251
|
+
textTag += '</span>'
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
logger.warn(`[KDK] text must contain the 'label' property`)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// Render html
|
|
258
|
+
let htmlTag = ''
|
|
259
|
+
if (options.html) {
|
|
260
|
+
htmlTag = '<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">'
|
|
261
|
+
htmlTag += options.html
|
|
262
|
+
htmlTag += '</div>'
|
|
263
|
+
}
|
|
264
|
+
return {
|
|
265
|
+
html: beginDivTag + beginSvgTag + svgClipPath + svgShapeContent + endSvgTag + iconTag + textTag + htmlTag + endDivTag,
|
|
266
|
+
size,
|
|
267
|
+
anchor
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|