@kalisio/kdk 2.6.3 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/api/application.js +2 -4
- package/core/api/authentication.js +2 -3
- package/core/api/db.js +10 -2
- package/core/api/hooks/hooks.authorisations.js +4 -2
- package/core/api/hooks/hooks.push.js +6 -2
- package/core/api/hooks/hooks.query.js +29 -12
- package/core/api/hooks/hooks.users.js +30 -17
- package/core/api/models/configurations.model.mongodb.js +4 -0
- package/core/api/services/authorisations/authorisations.service.js +1 -1
- package/core/api/services/configurations/configurations.hooks.js +33 -0
- package/core/api/services/index.js +41 -7
- package/core/api/services/messages/messages.hooks.js +9 -3
- package/core/client/api.js +14 -1
- package/core/client/capabilities.js +1 -6
- package/core/client/components/KAvatar.vue +24 -20
- package/core/client/components/account/KProfile.vue +10 -71
- package/core/client/components/account/index.js +0 -2
- package/core/client/components/app/KSettings.vue +1 -0
- package/core/client/components/collection/KBoard.vue +4 -3
- package/core/client/components/collection/KCardSection.vue +1 -0
- package/core/client/components/collection/KGrid.vue +2 -0
- package/core/client/components/collection/KTable.vue +5 -1
- package/core/client/components/collection/KTimeLine.vue +9 -1
- package/core/client/components/collection/index.js +0 -2
- package/core/client/components/form/KChipsField.vue +2 -1
- package/core/client/components/form/KEmailField.vue +1 -0
- package/core/client/components/form/KFileField.vue +22 -1
- package/core/client/components/form/KForm.vue +2 -0
- package/core/client/components/form/KItemField.vue +1 -0
- package/core/client/components/form/KNumberField.vue +1 -0
- package/core/client/components/form/KPasswordField.vue +1 -0
- package/core/client/components/form/KPhoneField.vue +1 -0
- package/core/client/components/form/KPropertyItemField.vue +1 -0
- package/core/client/components/form/KResolutionField.vue +1 -0
- package/core/client/components/form/KSelectField.vue +31 -0
- package/core/client/components/form/KTagField.vue +1 -0
- package/core/client/components/form/KTextField.vue +1 -0
- package/core/client/components/form/KTokenField.vue +1 -0
- package/core/client/components/form/KUnitField.vue +1 -0
- package/core/client/components/form/KUrlField.vue +1 -0
- package/core/client/components/graphics/KIcon.vue +3 -4
- package/core/client/components/layout/KPage.vue +1 -0
- package/core/client/components/layout/KWindow.vue +6 -3
- package/core/client/components/messages/KMessageComposer.vue +2 -1
- package/core/client/components/messages/KMessagesTimeLine.vue +1 -1
- package/core/client/components/time/KDate.vue +1 -2
- package/core/client/components/time/KDateTime.vue +11 -11
- package/core/client/components/time/KTime.vue +1 -1
- package/core/client/composables/collection.js +33 -8
- package/core/client/composables/errors.js +1 -1
- package/core/client/composables/layout.js +9 -9
- package/core/client/configurations.js +50 -0
- package/core/client/exporter.js +1 -1
- package/core/client/i18n/core_en.json +6 -39
- package/core/client/i18n/core_fr.json +6 -39
- package/core/client/index.js +2 -0
- package/core/client/layout.js +8 -8
- package/core/client/mixins/mixin.base-activity.js +5 -2
- package/core/client/mixins/mixin.base-field.js +3 -3
- package/core/client/search.js +2 -1
- package/core/client/utils/utils.collection.js +8 -8
- package/core/client/utils/utils.items.js +4 -0
- package/core/client/utils/utils.push.js +3 -3
- package/core/client/utils/utils.session.js +7 -5
- package/core/client/utils/utils.shapes.js +38 -7
- package/core/client/utils/utils.time.js +21 -22
- package/core/common/schemas/users.update-profile.json +3 -2
- package/coverage/core/api/application.js.html +1 -1
- package/coverage/core/api/authentication.js.html +1 -1
- package/coverage/core/api/db.js.html +1 -1
- package/coverage/core/api/hooks/hooks.authentication.js.html +1 -1
- package/coverage/core/api/hooks/hooks.authorisations.js.html +1 -1
- package/coverage/core/api/hooks/hooks.logger.js.html +1 -1
- package/coverage/core/api/hooks/hooks.model.js.html +1 -1
- package/coverage/core/api/hooks/hooks.push.js.html +22 -10
- package/coverage/core/api/hooks/hooks.query.js.html +33 -6
- package/coverage/core/api/hooks/hooks.schemas.js.html +1 -1
- package/coverage/core/api/hooks/hooks.service.js.html +1 -1
- package/coverage/core/api/hooks/hooks.storage.js.html +1 -1
- package/coverage/core/api/hooks/hooks.tags.js.html +1 -1
- package/coverage/core/api/hooks/hooks.users.js.html +4 -4
- package/coverage/core/api/hooks/index.html +23 -23
- package/coverage/core/api/hooks/index.js.html +1 -1
- package/coverage/core/api/index.html +1 -1
- package/coverage/core/api/index.js.html +1 -1
- package/coverage/core/api/marshall.js.html +1 -1
- package/coverage/core/api/models/configurations.model.mongodb.js.html +1 -1
- package/coverage/core/api/models/index.html +1 -1
- package/coverage/core/api/models/messages.model.mongodb.js.html +1 -1
- package/coverage/core/api/models/tags.model.mongodb.js.html +1 -1
- package/coverage/core/api/models/users.model.mongodb.js.html +1 -1
- package/coverage/core/api/services/account/account.hooks.js.html +1 -1
- package/coverage/core/api/services/account/account.service.js.html +1 -1
- package/coverage/core/api/services/account/index.html +1 -1
- package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
- package/coverage/core/api/services/authorisations/authorisations.service.js.html +1 -1
- package/coverage/core/api/services/authorisations/index.html +1 -1
- package/coverage/core/api/services/configurations/configurations.hooks.js.html +1 -1
- package/coverage/core/api/services/configurations/index.html +1 -1
- package/coverage/core/api/services/databases/databases.hooks.js.html +1 -1
- package/coverage/core/api/services/databases/databases.service.js.html +1 -1
- package/coverage/core/api/services/databases/index.html +1 -1
- package/coverage/core/api/services/import-export/import-export.hooks.js.html +1 -1
- package/coverage/core/api/services/import-export/import-export.service.js.html +1 -1
- package/coverage/core/api/services/import-export/index.html +1 -1
- package/coverage/core/api/services/index.html +1 -1
- package/coverage/core/api/services/index.js.html +1 -1
- package/coverage/core/api/services/mailer/index.html +1 -1
- package/coverage/core/api/services/mailer/mailer.hooks.js.html +1 -1
- package/coverage/core/api/services/mailer/mailer.service.js.html +1 -1
- package/coverage/core/api/services/messages/index.html +1 -1
- package/coverage/core/api/services/messages/messages.hooks.js.html +1 -1
- package/coverage/core/api/services/push/index.html +1 -1
- package/coverage/core/api/services/push/push.hooks.js.html +1 -1
- package/coverage/core/api/services/push/push.service.js.html +1 -1
- package/coverage/core/api/services/storage/index.html +1 -1
- package/coverage/core/api/services/storage/storage.hooks.js.html +1 -1
- package/coverage/core/api/services/storage/storage.service.js.html +1 -1
- package/coverage/core/api/services/tags/index.html +1 -1
- package/coverage/core/api/services/tags/tags.hooks.js.html +1 -1
- package/coverage/core/api/services/users/index.html +1 -1
- package/coverage/core/api/services/users/users.hooks.js.html +1 -1
- package/coverage/core/api/services/users/users.service.js.html +1 -1
- package/coverage/core/common/errors.js.html +1 -1
- package/coverage/core/common/index.html +1 -1
- package/coverage/core/common/index.js.html +1 -1
- package/coverage/core/common/permissions.js.html +1 -1
- package/coverage/core/common/schema.js.html +1 -1
- package/coverage/core/common/utils.js.html +1 -1
- package/coverage/core/common/utils.offline.js.html +1 -1
- package/coverage/index.html +17 -17
- package/coverage/lcov-report/core/api/application.js.html +1 -1
- package/coverage/lcov-report/core/api/authentication.js.html +1 -1
- package/coverage/lcov-report/core/api/db.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +22 -10
- package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +33 -6
- package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.tags.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +4 -4
- package/coverage/lcov-report/core/api/hooks/index.html +23 -23
- package/coverage/lcov-report/core/api/hooks/index.js.html +1 -1
- package/coverage/lcov-report/core/api/index.html +1 -1
- package/coverage/lcov-report/core/api/index.js.html +1 -1
- package/coverage/lcov-report/core/api/marshall.js.html +1 -1
- package/coverage/lcov-report/core/api/models/configurations.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/core/api/models/index.html +1 -1
- package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/account/account.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/account/index.html +1 -1
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/authorisations/index.html +1 -1
- package/coverage/lcov-report/core/api/services/configurations/configurations.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/configurations/index.html +1 -1
- package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/databases/index.html +1 -1
- package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/import-export/index.html +1 -1
- package/coverage/lcov-report/core/api/services/index.html +1 -1
- package/coverage/lcov-report/core/api/services/index.js.html +1 -1
- package/coverage/lcov-report/core/api/services/mailer/index.html +1 -1
- package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/messages/index.html +1 -1
- package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/push/index.html +1 -1
- package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/push/push.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/storage/index.html +1 -1
- package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/tags/index.html +1 -1
- package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/users/index.html +1 -1
- package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/users/users.service.js.html +1 -1
- package/coverage/lcov-report/core/common/errors.js.html +1 -1
- package/coverage/lcov-report/core/common/index.html +1 -1
- package/coverage/lcov-report/core/common/index.js.html +1 -1
- package/coverage/lcov-report/core/common/permissions.js.html +1 -1
- package/coverage/lcov-report/core/common/schema.js.html +1 -1
- package/coverage/lcov-report/core/common/utils.js.html +1 -1
- package/coverage/lcov-report/core/common/utils.offline.js.html +1 -1
- package/coverage/lcov-report/index.html +17 -17
- package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +1 -1
- package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +1 -1
- package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +184 -4
- package/coverage/lcov-report/map/api/hooks/index.html +5 -5
- package/coverage/lcov-report/map/api/hooks/index.js.html +1 -1
- package/coverage/lcov-report/map/api/index.html +1 -1
- package/coverage/lcov-report/map/api/index.js.html +1 -1
- package/coverage/lcov-report/map/api/marshall.js.html +1 -1
- package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/models/index.html +1 -1
- package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/models/styles.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +1 -1
- package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +1 -1
- package/coverage/lcov-report/map/api/services/alerts/index.html +1 -1
- package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +1 -1
- package/coverage/lcov-report/map/api/services/catalog/index.html +1 -1
- package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1 -1
- package/coverage/lcov-report/map/api/services/daptiles/index.html +1 -1
- package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +1 -1
- package/coverage/lcov-report/map/api/services/features/features.service.js.html +1 -1
- package/coverage/lcov-report/map/api/services/features/index.html +1 -1
- package/coverage/lcov-report/map/api/services/index.html +1 -1
- package/coverage/lcov-report/map/api/services/index.js.html +1 -1
- package/coverage/lcov-report/map/api/services/projects/index.html +1 -1
- package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +1 -1
- package/coverage/lcov-report/map/api/services/styles/index.html +1 -1
- package/coverage/lcov-report/map/api/services/styles/styles.hooks.js.html +1 -1
- package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/errors.js.html +1 -1
- package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/grid.js.html +1 -1
- package/coverage/lcov-report/map/common/index.html +1 -1
- package/coverage/lcov-report/map/common/index.js.html +1 -1
- package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/moment-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/opendap-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/opendap-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/permissions.js.html +1 -1
- package/coverage/lcov-report/map/common/time-based-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/tms-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/wcs-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/wcs-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/weacast-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/wfs-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/wms-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/wmts-utils.js.html +1 -1
- package/coverage/lcov.info +358 -280
- package/coverage/map/api/hooks/hooks.catalog.js.html +1 -1
- package/coverage/map/api/hooks/hooks.features.js.html +1 -1
- package/coverage/map/api/hooks/hooks.query.js.html +184 -4
- package/coverage/map/api/hooks/index.html +5 -5
- package/coverage/map/api/hooks/index.js.html +1 -1
- package/coverage/map/api/index.html +1 -1
- package/coverage/map/api/index.js.html +1 -1
- package/coverage/map/api/marshall.js.html +1 -1
- package/coverage/map/api/models/alerts.model.mongodb.js.html +1 -1
- package/coverage/map/api/models/catalog.model.mongodb.js.html +1 -1
- package/coverage/map/api/models/features.model.mongodb.js.html +1 -1
- package/coverage/map/api/models/index.html +1 -1
- package/coverage/map/api/models/projects.model.mongodb.js.html +1 -1
- package/coverage/map/api/models/styles.model.mongodb.js.html +1 -1
- package/coverage/map/api/services/alerts/alerts.hooks.js.html +1 -1
- package/coverage/map/api/services/alerts/alerts.service.js.html +1 -1
- package/coverage/map/api/services/alerts/index.html +1 -1
- package/coverage/map/api/services/catalog/catalog.hooks.js.html +1 -1
- package/coverage/map/api/services/catalog/index.html +1 -1
- package/coverage/map/api/services/daptiles/daptiles.service.js.html +1 -1
- package/coverage/map/api/services/daptiles/index.html +1 -1
- package/coverage/map/api/services/features/features.hooks.js.html +1 -1
- package/coverage/map/api/services/features/features.service.js.html +1 -1
- package/coverage/map/api/services/features/index.html +1 -1
- package/coverage/map/api/services/index.html +1 -1
- package/coverage/map/api/services/index.js.html +1 -1
- package/coverage/map/api/services/projects/index.html +1 -1
- package/coverage/map/api/services/projects/projects.hooks.js.html +1 -1
- package/coverage/map/api/services/styles/index.html +1 -1
- package/coverage/map/api/services/styles/styles.hooks.js.html +1 -1
- package/coverage/map/common/dynamic-grid-source.js.html +1 -1
- package/coverage/map/common/errors.js.html +1 -1
- package/coverage/map/common/geotiff-grid-source.js.html +1 -1
- package/coverage/map/common/grid.js.html +1 -1
- package/coverage/map/common/index.html +1 -1
- package/coverage/map/common/index.js.html +1 -1
- package/coverage/map/common/meteo-model-grid-source.js.html +1 -1
- package/coverage/map/common/moment-utils.js.html +1 -1
- package/coverage/map/common/opendap-grid-source.js.html +1 -1
- package/coverage/map/common/opendap-utils.js.html +1 -1
- package/coverage/map/common/permissions.js.html +1 -1
- package/coverage/map/common/time-based-grid-source.js.html +1 -1
- package/coverage/map/common/tms-utils.js.html +1 -1
- package/coverage/map/common/wcs-grid-source.js.html +1 -1
- package/coverage/map/common/wcs-utils.js.html +1 -1
- package/coverage/map/common/weacast-grid-source.js.html +1 -1
- package/coverage/map/common/wfs-utils.js.html +1 -1
- package/coverage/map/common/wms-utils.js.html +1 -1
- package/coverage/map/common/wmts-utils.js.html +1 -1
- package/coverage/tmp/coverage-1028514-1773134124472-0.json +1 -0
- package/coverage/tmp/coverage-1028526-1773134124448-0.json +1 -0
- package/coverage/tmp/coverage-1028537-1773134124431-0.json +1 -0
- package/coverage/tmp/coverage-1028549-1773134124401-0.json +1 -0
- package/coverage/tmp/{coverage-222566-1765963609278-0.json → coverage-1028556-1773134124353-0.json} +1 -1
- package/extras/configs/widgets.top.js +3 -3
- package/extras/tests/core/collection.mjs +2 -9
- package/map/api/hooks/hooks.catalog.js +18 -4
- package/map/api/services/catalog/catalog.hooks.js +3 -0
- package/map/api/services/features/features.hooks.js +3 -1
- package/map/api/services/index.js +2 -6
- package/map/api/services/styles/styles.hooks.js +6 -1
- package/map/client/components/KFeatureActionButton.vue +9 -3
- package/map/client/components/KFeaturesFilterManager.vue +5 -5
- package/map/client/components/KFilterCondition.vue +17 -10
- package/map/client/components/KLayerEditor.vue +49 -39
- package/map/client/components/KMeasureTool.vue +7 -1
- package/map/client/components/KTimezoneMap.vue +29 -9
- package/map/client/components/catalog/KLayersPanel.vue +26 -16
- package/map/client/components/catalog/KLayersSelector.vue +13 -2
- package/map/client/components/catalog/KViewsPanel.vue +5 -4
- package/map/client/components/form/KSelectLayersField.vue +28 -17
- package/map/client/components/form/KSelectViewsField.vue +18 -9
- package/map/client/components/form/KTimezoneField.vue +1 -2
- package/map/client/components/legend/KVariablesLegend.vue +10 -1
- package/map/client/components/location/KLocationCardSection.vue +7 -2
- package/map/client/components/location/KLocationMap.vue +31 -7
- package/map/client/components/selection/KSelectedLayerFeatures.vue +2 -2
- package/map/client/components/stickies/KZoomControl.vue +1 -1
- package/map/client/components/styles/KStyleManager.vue +4 -1
- package/map/client/components/widget/KTimeSeries.vue +174 -497
- package/map/client/components/widget/KTimeSeriesSelector.vue +72 -0
- package/map/client/components/widget/KTimeSeriesToolbar.vue +83 -0
- package/map/client/composables/catalog.js +6 -10
- package/map/client/composables/highlight.js +12 -9
- package/map/client/composables/project.js +1 -1
- package/map/client/composables/selection.js +8 -7
- package/map/client/composables/weather.js +9 -2
- package/map/client/geolocation.js +8 -5
- package/map/client/i18n/map_en.json +10 -8
- package/map/client/i18n/map_fr.json +9 -7
- package/map/client/leaflet/TiledFeatureLayer.js +85 -82
- package/map/client/leaflet/utils/utils.geojson.js +3 -3
- package/map/client/mixins/globe/mixin.base-globe.js +15 -6
- package/map/client/mixins/globe/mixin.geojson-layers.js +27 -18
- package/map/client/mixins/map/mixin.edit-layers.js +9 -1
- package/map/client/mixins/map/mixin.pmtiles-layers.js +118 -29
- package/map/client/mixins/map/mixin.tiled-mesh-layers.js +12 -5
- package/map/client/mixins/map/mixin.tiled-wind-layers.js +19 -10
- package/map/client/mixins/mixin.activity.js +23 -30
- package/map/client/mixins/mixin.feature-selection.js +41 -5
- package/map/client/planets.js +1 -1
- package/map/client/readers/reader.kml.js +2 -3
- package/map/client/utils/utils.catalog.js +36 -10
- package/map/client/utils/utils.layers.js +39 -8
- package/map/client/utils/utils.project.js +4 -0
- package/map/client/utils/utils.style.js +37 -7
- package/map/client/utils/utils.time-series.js +215 -6
- package/map/common/schemas/catalog.update.json +1 -1
- package/map/common/weacast-grid-source.js +1 -1
- package/package.json +3 -3
- package/scripts/kash/CHANGELOG.md +0 -4
- package/scripts/kash/README.md +0 -9
- package/scripts/kash/kash.sh +45 -40
- package/scripts/kash/scripts/run_tests.sh +1 -4
- package/test/api/core/authentication.test.js +9 -4
- package/test/api/core/config/default.cjs +1 -0
- package/test/api/core/hooks.test.js +6 -0
- package/test/api/core/index.test.js +43 -18
- package/test/api/core/push.test.js +8 -8
- package/test/api/core/test-log-2026-03-10.log +60 -0
- package/test/api/core/users.test.js +384 -0
- package/test/api/map/grid-sources.test.js +1 -1
- package/test/api/map/test-log-2026-03-10.log +56 -0
- package/vite/package.json +11 -2
- package/vite/test/core/composables.test.js +77 -0
- package/vite/vitest.config.js +13 -0
- package/vite/yarn.lock +1096 -18
- package/client/css/core.variables.scss +0 -72
- package/client/i18n/core_en.json +0 -744
- package/client/i18n/core_fr.json +0 -744
- package/client/i18n/map_en.json +0 -800
- package/client/i18n/map_fr.json +0 -800
- package/client/kdk.client.css +0 -47
- package/client/kdk.client.js +0 -41097
- package/client/kdk.client.map.css +0 -47
- package/client/kdk.client.map.js +0 -38182
- package/client/kdk.client.map.min.css +0 -1
- package/client/kdk.client.map.min.js +0 -27032
- package/client/kdk.client.min.css +0 -1
- package/client/kdk.client.min.js +0 -29074
- package/client/schemas/capture.create.json +0 -132
- package/client/schemas/catalog.update.json +0 -44
- package/client/schemas/messages.update.json +0 -16
- package/client/schemas/projects.create.json +0 -52
- package/client/schemas/projects.update.json +0 -52
- package/client/schemas/settings.update.json +0 -286
- package/client/schemas/tags.update.json +0 -35
- package/client/schemas/users.update-profile.json +0 -34
- package/core/client/components/account/KAccount.vue +0 -68
- package/core/client/components/account/KDeleteAccountManager.vue +0 -62
- package/core/client/components/account/KEmailManager.vue +0 -128
- package/core/client/components/account/KPasswordManager.vue +0 -90
- package/core/client/components/account/KVerifyEmailManager.vue +0 -105
- package/core/client/components/collection/KColumn.vue +0 -227
- package/core/client/components/collection/KHistory.vue +0 -113
- package/core/client/components/collection/KHistoryEntry.vue +0 -109
- package/coverage/tmp/coverage-222524-1765963609350-0.json +0 -1
- package/coverage/tmp/coverage-222536-1765963609335-0.json +0 -1
- package/coverage/tmp/coverage-222547-1765963609324-0.json +0 -1
- package/coverage/tmp/coverage-222559-1765963609309-0.json +0 -1
- package/scripts/kash/LICENSE +0 -21
- package/test/api/core/test-log-2025-07-31.log +0 -15
- package/test/api/core/test-log-2025-10-03.log +0 -18
- package/test/api/core/test-log-2025-11-10.log +0 -0
- package/test/api/core/test-log-2025-11-12.log +0 -117
- package/test/api/core/test-log-2025-11-27.log +0 -0
- package/test/api/core/test-log-2025-11-28.log +0 -17
- package/test/api/core/test-log-2025-12-09.log +0 -148
- package/test/api/core/test-log-2025-12-17.log +0 -58
- package/test/api/core/test-log-2026-01-29.log +0 -17
- package/test/api/map/test-log-2025-07-23.log +0 -1
- package/test/api/map/test-log-2025-11-28.log +0 -33
- package/test/api/map/test-log-2025-12-10.log +0 -2
- package/test/api/map/test-log-2026-01-06.log +0 -26
|
@@ -1,508 +1,185 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
<
|
|
2
|
+
<div class="column justify-start no-wrap">
|
|
3
|
+
<q-resize-observer @resize="onResized" />
|
|
4
|
+
<q-splitter v-if="isSelectorVisible" v-model="splitterModel" :style="`height: ${height}px`">
|
|
5
|
+
<template v-slot:before>
|
|
6
|
+
<KTimeSeriesSelector
|
|
7
|
+
:menu="false"
|
|
8
|
+
/>
|
|
9
|
+
</template>
|
|
10
|
+
<template v-slot:after>
|
|
11
|
+
<div class="fit column justify-start no-wrap">
|
|
12
|
+
<KStackableTimeSeries
|
|
13
|
+
ref="chartRef"
|
|
14
|
+
class="col"
|
|
15
|
+
:time-series="timeSeries"
|
|
16
|
+
:chart-options="chartOptions"
|
|
17
|
+
:actions="actions"
|
|
18
|
+
@zoom-end="onZoomEnd"
|
|
19
|
+
/>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
22
|
+
</q-splitter>
|
|
23
|
+
<div v-else class="col column justify-start no-wrap">
|
|
24
|
+
<KStackableTimeSeries
|
|
25
|
+
ref="chartRef"
|
|
26
|
+
class="col"
|
|
27
|
+
:time-series="timeSeries"
|
|
28
|
+
:chart-options="chartOptions"
|
|
29
|
+
:actions="actions"
|
|
30
|
+
@zoom-end="onZoomEnd"
|
|
31
|
+
/>
|
|
32
|
+
</div>
|
|
4
33
|
</div>
|
|
5
34
|
</template>
|
|
6
35
|
|
|
7
|
-
<script>
|
|
36
|
+
<script setup>
|
|
8
37
|
import _ from 'lodash'
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import { Store } from '../../../../core/client/store'
|
|
15
|
-
import { Units } from '../../../../core/client/units'
|
|
16
|
-
import { Time } from '../../../../core/client/time'
|
|
17
|
-
import { Events } from '../../../../core/client/events'
|
|
18
|
-
import { KChart } from '../../../../core/client/components'
|
|
19
|
-
import { useCurrentActivity, useWeather, useMeasure, useHighlight } from '../../composables'
|
|
20
|
-
import 'chartjs-adapter-moment'
|
|
21
|
-
import { getCssVar } from 'quasar'
|
|
38
|
+
import { ref, computed, watch } from 'vue'
|
|
39
|
+
import { Store, composables as kCoreComposables } from '../../../../core/client/index.js'
|
|
40
|
+
import KStackableTimeSeries from './KStackableTimeSeries.vue'
|
|
41
|
+
import KTimeSeriesSelector from './KTimeSeriesSelector.vue'
|
|
42
|
+
import { getChartOptions } from '../../utils/utils.time-series.js'
|
|
22
43
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
default: () => ({ 'stroke-color': 'primary', 'fill-opacity': 0, zOrder: 1 })
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
computed: {
|
|
35
|
-
title () {
|
|
36
|
-
// Compute the layer name if any
|
|
37
|
-
const layerName = this.hasSelectedFeature() && this.getSelectedLayer() ? this.$t(this.getSelectedLayer().name) : undefined
|
|
38
|
-
// Compute the probe location name
|
|
39
|
-
let probeName
|
|
40
|
-
if (this.probedLocation) {
|
|
41
|
-
// Check if we have a property as tooltip or popup and use it
|
|
42
|
-
if (this.hasSelectedLayer()) {
|
|
43
|
-
const probeNameProperty = _.get(this.getSelectedLayer(), `${this.kActivity.engine}.tooltip.property`,
|
|
44
|
-
_.get(this.getSelectedLayer(), `${this.kActivity.engine}.popup.pick[0]`))
|
|
45
|
-
if (probeNameProperty) probeName = _.get(this.probedLocation, `properties.${probeNameProperty}`)
|
|
46
|
-
}
|
|
47
|
-
// Otherwise test for conventional names otherwise
|
|
48
|
-
if (!probeName) probeName = _.get(this.probedLocation, 'properties.name', _.get(this.probedLocation, 'properties.NAME'))
|
|
49
|
-
}
|
|
50
|
-
if (layerName && probeName) return `${layerName} - ${probeName}`
|
|
51
|
-
if (probeName) return probeName
|
|
52
|
-
return ''
|
|
53
|
-
},
|
|
54
|
-
location () {
|
|
55
|
-
if (this.hasSelectedLocation()) return this.getSelectedLocation()
|
|
56
|
-
else if (this.hasProbedLocation()) return this.getProbedLocation()
|
|
57
|
-
},
|
|
58
|
-
feature () {
|
|
59
|
-
return this.hasSelectedFeature() && this.getSelectedFeature()
|
|
60
|
-
},
|
|
61
|
-
layer () {
|
|
62
|
-
if (this.hasSelectedLayer()) return this.getSelectedLayer()
|
|
63
|
-
else if (this.hasProbedLayer()) return this.getProbedLayer()
|
|
64
|
-
},
|
|
65
|
-
probedVariables () {
|
|
66
|
-
// If the feature is linked to a layer with variables use it
|
|
67
|
-
// Otherwise use all available variables to search for those applicable to it
|
|
68
|
-
return (this.layer && this.layer.variables ? this.layer.variables : this.kActivity.variables)
|
|
69
|
-
},
|
|
70
|
-
runOptions () {
|
|
71
|
-
// Build options from runtimes for UI
|
|
72
|
-
let runOptions = []
|
|
73
|
-
if (this.hasRunTimes()) {
|
|
74
|
-
runOptions = this.runTimes.map(runTime => ({
|
|
75
|
-
label: Time.format(runTime, 'date.short') + ' - ' + Time.format(runTime, 'time.short'),
|
|
76
|
-
value: runTime
|
|
77
|
-
}))
|
|
78
|
-
// Select latest runTime as default option
|
|
79
|
-
_.last(runOptions).default = true
|
|
80
|
-
}
|
|
81
|
-
return runOptions
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
watch: {
|
|
85
|
-
variables: function () {
|
|
86
|
-
this.refresh()
|
|
87
|
-
},
|
|
88
|
-
// This also cover the case where the feature changes
|
|
89
|
-
location: function () {
|
|
90
|
-
this.refresh()
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
data () {
|
|
94
|
-
return {
|
|
95
|
-
probedLocation: null,
|
|
96
|
-
zoomHistory: [],
|
|
97
|
-
runTime: null,
|
|
98
|
-
runTimes: []
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
methods: {
|
|
102
|
-
hasVariable (name, properties, match) {
|
|
103
|
-
// The feature target the variable if it has at least the target variable value name
|
|
104
|
-
let hasVariable = (properties[name] && Array.isArray(properties[name]))
|
|
105
|
-
// Test if the variable needs to match additional properties
|
|
106
|
-
// in case multiple variables target the same property value name
|
|
107
|
-
if (match) {
|
|
108
|
-
_.forOwn(match, (value, key) => { hasVariable = hasVariable && (properties[key] === value) })
|
|
109
|
-
}
|
|
110
|
-
return hasVariable
|
|
111
|
-
},
|
|
112
|
-
hasZoomHistory () {
|
|
113
|
-
return this.zoomHistory.length > 0
|
|
114
|
-
},
|
|
115
|
-
getBaseUnit (variable, properties) {
|
|
116
|
-
const unit = variable.unit
|
|
117
|
-
// Could be either directly the unit or the property of the measure storing the unit
|
|
118
|
-
return _.get(properties, unit, unit)
|
|
119
|
-
},
|
|
120
|
-
hasRunTimes () {
|
|
121
|
-
return this.runTimes && (this.runTimes.length > 1)
|
|
122
|
-
},
|
|
123
|
-
getSelectedRunTime () {
|
|
124
|
-
// Set default run as latest
|
|
125
|
-
return this.runTime || _.last(this.runTimes)
|
|
126
|
-
},
|
|
127
|
-
setupAvailableRunTimes () {
|
|
128
|
-
this.runTimes = []
|
|
129
|
-
const runTime = this.probedLocation.runTime
|
|
130
|
-
this.probedVariables.forEach(variable => {
|
|
131
|
-
if (!variable.runTimes) return
|
|
132
|
-
// Check if we are targetting a specific level
|
|
133
|
-
const name = (this.kActivity.forecastLevel ? `${variable.name}-${this.kActivity.forecastLevel}` : variable.name)
|
|
44
|
+
// Data
|
|
45
|
+
const chartRef = ref(null)
|
|
46
|
+
const chartOptions = ref(getChartOptions())
|
|
47
|
+
const splitterModel = ref(25)
|
|
48
|
+
const isZoomed = ref(false)
|
|
49
|
+
const height = ref(0)
|
|
50
|
+
const { CurrentActivityContext } = kCoreComposables.useCurrentActivity()
|
|
51
|
+
const { state } = CurrentActivityContext
|
|
134
52
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
mode: 'vertical',
|
|
243
|
-
scaleID: 'x',
|
|
244
|
-
value: currentTime.toDate(),
|
|
245
|
-
borderColor: 'grey',
|
|
246
|
-
borderWidth: 1,
|
|
247
|
-
label: {
|
|
248
|
-
backgroundColor: 'rgba(0,0,0,0.65)',
|
|
249
|
-
content: _.get(Time.getCurrentFormattedTime(), 'time.long'),
|
|
250
|
-
position: 'start',
|
|
251
|
-
enabled: true
|
|
252
|
-
}
|
|
253
|
-
})
|
|
254
|
-
}
|
|
255
|
-
// Display also time of probed feature, only if single variable
|
|
256
|
-
if ((this.probedVariables.length === 1) && this.feature && this.feature.time) {
|
|
257
|
-
const time = moment.utc(this.feature.time[this.probedVariables[0].name])
|
|
258
|
-
if (time.isBetween(timeRange.start, timeRange.end)) {
|
|
259
|
-
annotations.push({
|
|
260
|
-
type: 'line',
|
|
261
|
-
mode: 'vertical',
|
|
262
|
-
scaleID: 'x',
|
|
263
|
-
value: time.toDate(),
|
|
264
|
-
borderColor: 'green',
|
|
265
|
-
borderWidth: 1,
|
|
266
|
-
label: {
|
|
267
|
-
backgroundColor: 'rgba(0,0,0,0.65)',
|
|
268
|
-
content: Time.format(time, 'time.long'),
|
|
269
|
-
position: 'start',
|
|
270
|
-
enabled: true
|
|
271
|
-
}
|
|
272
|
-
})
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
this.chart.update({
|
|
276
|
-
type: 'line',
|
|
277
|
-
data: {
|
|
278
|
-
labels: this.times,
|
|
279
|
-
datasets: this.datasets
|
|
280
|
-
},
|
|
281
|
-
options: _.merge({
|
|
282
|
-
maintainAspectRatio: false,
|
|
283
|
-
animation: false,
|
|
284
|
-
parsing: false,
|
|
285
|
-
spanGaps: timeSpanGaps,
|
|
286
|
-
scales: {
|
|
287
|
-
x: {
|
|
288
|
-
type: 'time',
|
|
289
|
-
time: {
|
|
290
|
-
unit: 'hour'
|
|
291
|
-
},
|
|
292
|
-
ticks: {
|
|
293
|
-
autoskip: true,
|
|
294
|
-
maxRotation: 20,
|
|
295
|
-
major: {
|
|
296
|
-
enabled: true
|
|
297
|
-
},
|
|
298
|
-
callback: function (value, index, values) {
|
|
299
|
-
if (values[index] !== undefined) {
|
|
300
|
-
if (values[index].major === true) {
|
|
301
|
-
return Time.format(moment(values[index].value), 'date.short')
|
|
302
|
-
} else {
|
|
303
|
-
return Time.format(moment(values[index].value), 'time.short')
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
},
|
|
307
|
-
font: function (context) {
|
|
308
|
-
if (context.tick && context.tick.major) {
|
|
309
|
-
return {
|
|
310
|
-
weight: 'bold'
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
},
|
|
317
|
-
plugins: {
|
|
318
|
-
title: {
|
|
319
|
-
display: true,
|
|
320
|
-
text: this.title,
|
|
321
|
-
align: 'start'
|
|
322
|
-
},
|
|
323
|
-
datalabels: {
|
|
324
|
-
display: false
|
|
325
|
-
},
|
|
326
|
-
tooltip: {
|
|
327
|
-
mode: 'x',
|
|
328
|
-
callbacks: {
|
|
329
|
-
title: (context) => {
|
|
330
|
-
// As we are selecting tooltip items based on x coordinate all should have the same one, which is actually the time
|
|
331
|
-
const x = _.get(context, '[0].parsed.x')
|
|
332
|
-
return (x ? `${Time.format(x, 'date.short')} - ${Time.format(x, 'time.short')}` : '')
|
|
333
|
-
},
|
|
334
|
-
label: (context) => {
|
|
335
|
-
const { unit, label } = context.dataset
|
|
336
|
-
const y = _.get(context, 'parsed.y')
|
|
337
|
-
// We have unit in label name for legend but we want it after the value for tooltip
|
|
338
|
-
return label.replace(`(${Units.getTargetUnitSymbol(unit)})`, '') + ': ' + Units.format(y, unit)
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
},
|
|
342
|
-
annotation: {
|
|
343
|
-
annotations
|
|
344
|
-
},
|
|
345
|
-
zoom: {
|
|
346
|
-
zoom: {
|
|
347
|
-
drag: {
|
|
348
|
-
enabled: true,
|
|
349
|
-
backgroundColor: getCssVar('secondary')
|
|
350
|
-
},
|
|
351
|
-
mode: 'x',
|
|
352
|
-
onZoomStart: this.onZoomStarted,
|
|
353
|
-
onZoom: this.onZoomed
|
|
354
|
-
}
|
|
355
|
-
},
|
|
356
|
-
decimation: {
|
|
357
|
-
enabled: true,
|
|
358
|
-
algorithm: 'lttb'
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}, { scales: this.yAxes })
|
|
362
|
-
})
|
|
363
|
-
} catch (error) {
|
|
364
|
-
logger.error(error)
|
|
365
|
-
}
|
|
366
|
-
this.buildingChart = false
|
|
367
|
-
},
|
|
368
|
-
onUpdateRun (runTime) {
|
|
369
|
-
this.runTime = runTime
|
|
370
|
-
this.setupGraph()
|
|
371
|
-
},
|
|
372
|
-
updateProbedLocationHighlight () {
|
|
373
|
-
this.clearHighlights()
|
|
374
|
-
if (!this.probedLocation) return
|
|
375
|
-
const isWeatherProbe = this.isWeatherProbe(this.probedLocation)
|
|
376
|
-
const feature = (isWeatherProbe
|
|
377
|
-
? this.getProbedLocationForecastAtCurrentTime(this.probedLocation)
|
|
378
|
-
: this.getProbedLocationMeasureAtCurrentTime(this.probedLocation))
|
|
379
|
-
this.highlight(feature, this.layer)
|
|
380
|
-
},
|
|
381
|
-
onZoomRestored () {
|
|
382
|
-
if (!_.isEmpty(this.zoomHistory)) {
|
|
383
|
-
Time.patchRange(_.last(this.zoomHistory))
|
|
384
|
-
this.zoomHistory = _.slice(this.zoomHistory, 0, this.zoomHistory.length - 1)
|
|
385
|
-
}
|
|
386
|
-
},
|
|
387
|
-
onZoomStarted ({ chart }) {
|
|
388
|
-
this.zoomHistory.push({
|
|
389
|
-
start: moment(Time.getRange().start),
|
|
390
|
-
end: moment(Time.getRange().end)
|
|
391
|
-
})
|
|
392
|
-
},
|
|
393
|
-
onZoomed ({ chart }) {
|
|
394
|
-
const start = moment(_.get(chart, 'scales.x.min'))
|
|
395
|
-
const end = moment(_.get(chart, 'scales.x.max'))
|
|
396
|
-
Time.patchRange({ start, end })
|
|
397
|
-
},
|
|
398
|
-
onCenterOn () {
|
|
399
|
-
this.kActivity.centerOnSelection()
|
|
400
|
-
},
|
|
401
|
-
onExportSeries () {
|
|
402
|
-
let times = []
|
|
403
|
-
const time = _.get(this.probedLocation, 'time', _.get(this.probedLocation, 'forecastTime'))
|
|
404
|
-
this.probedVariables.forEach(variable => {
|
|
405
|
-
// Check if we are targetting a specific level
|
|
406
|
-
const name = (this.kActivity.forecastLevel ? `${variable.name}-${this.kActivity.forecastLevel}` : variable.name)
|
|
407
|
-
if (time && time[name]) times.push(time[name])
|
|
408
|
-
})
|
|
409
|
-
// Make union of all available times for x-axis
|
|
410
|
-
times = _.union(...times).map(time => moment.utc(time)).sort((a, b) => a - b)
|
|
411
|
-
// Convert to json
|
|
412
|
-
const json = times.map(time => {
|
|
413
|
-
const row = {
|
|
414
|
-
[this.$t('KTimeSeries.TIME_LABEL')]: time.toISOString()
|
|
415
|
-
}
|
|
416
|
-
this.datasets.forEach(dataset => {
|
|
417
|
-
const value = _.find(dataset.data, item => moment.utc(item.x).toISOString() === time.toISOString())
|
|
418
|
-
row[dataset.label] = value ? value.y : null
|
|
419
|
-
})
|
|
420
|
-
return row
|
|
421
|
-
})
|
|
422
|
-
// Convert to csv
|
|
423
|
-
const csv = Papa.unparse(json)
|
|
424
|
-
let filename = (this.title ? this.title.replace(/\s/g, '') : this.$t('KTimeSeries.SERIES_EXPORT_FILE'))
|
|
425
|
-
filename += '_' + new Date().toLocaleString()
|
|
426
|
-
downloadAsBlob(csv, _.snakeCase(filename) + '.csv', 'text/csv;charset=utf-8;')
|
|
427
|
-
},
|
|
428
|
-
async refresh () {
|
|
429
|
-
// Clear previous run time setup if any
|
|
430
|
-
this.runTime = null
|
|
431
|
-
this.probedLocation = null
|
|
432
|
-
this.clearHighlights()
|
|
433
|
-
if (!this.location) {
|
|
434
|
-
// Clear current graph if any
|
|
435
|
-
this.chart.clear()
|
|
436
|
-
return
|
|
437
|
-
}
|
|
438
|
-
// Then manage selection
|
|
439
|
-
this.highlight(this.location, this.layer)
|
|
440
|
-
if (this.hasProbedLocation()) this.centerOnProbe()
|
|
441
|
-
else this.centerOnSelection()
|
|
442
|
-
// Update timeseries data if required
|
|
443
|
-
const { start, end } = Time.getRange()
|
|
444
|
-
// No feature clicked => dynamic weacast probe at position
|
|
445
|
-
if (!this.feature) {
|
|
446
|
-
if (this.kActivity.probeLocation) { // Maybe there's a specific probeLocation function
|
|
447
|
-
this.probedLocation = await this.kActivity.probeLocation(this.location.lng, this.location.lat, start, end)
|
|
448
|
-
}
|
|
449
|
-
if (!this.probedLocation) {
|
|
450
|
-
this.probedLocation = await this.kActivity.getForecastForLocation(this.location.lng, this.location.lat, start, end)
|
|
451
|
-
_.set(this.probedLocation, 'properties.name', this.$t('mixins.timeseries.FORECAST_PROBE') +
|
|
452
|
-
` (${this.location.lng.toFixed(2)}°, ${this.location.lat.toFixed(2)}°)`)
|
|
453
|
-
}
|
|
454
|
-
} else if (this.layer.probe) { // Static weacast probe
|
|
455
|
-
const probe = await this.kActivity.getForecastProbe(this.layer.probe)
|
|
456
|
-
if (probe) {
|
|
457
|
-
this.probedLocation = await this.kActivity.getForecastForFeature(_.get(this.feature, probe.featureId), start, end)
|
|
458
|
-
}
|
|
459
|
-
} else if (this.layer.variables && this.layer.service) { // Static measure probe
|
|
460
|
-
this.probedLocation = await this.kActivity.getMeasureForFeature(this.layer, this.feature, start, end)
|
|
461
|
-
} else { // dynamic weacast probe at feature position
|
|
462
|
-
const name = _.get(this.feature, 'properties.name', _.get(this.feature, 'properties.NAME'))
|
|
463
|
-
const location = centroid(this.feature)
|
|
464
|
-
const longitude = _.get(location, 'geometry.coordinates[0]')
|
|
465
|
-
const latitude = _.get(location, 'geometry.coordinates[1]')
|
|
466
|
-
this.probedLocation = await this.kActivity.getForecastForLocation(longitude, latitude, start, end)
|
|
467
|
-
_.set(this.probedLocation, 'properties.name', this.$t('mixins.timeseries.FORECAST_PROBE') +
|
|
468
|
-
(name ? ` (${name})` : ` (${longitude.toFixed(2)}°, ${latitude.toFixed(2)}°)`))
|
|
469
|
-
}
|
|
470
|
-
await this.setupGraph()
|
|
471
|
-
this.updateProbedLocationHighlight()
|
|
472
|
-
}
|
|
473
|
-
},
|
|
474
|
-
async mounted () {
|
|
475
|
-
// Initialize the time range
|
|
476
|
-
const span = Store.get('timeseries.span')
|
|
477
|
-
const start = moment(Time.getCurrentTime()).subtract(span, 'm')
|
|
478
|
-
const end = moment(Time.getCurrentTime()).add(span, 'm')
|
|
479
|
-
Time.patchRange({ start, end })
|
|
480
|
-
// Force a first refresh
|
|
481
|
-
await this.refresh()
|
|
482
|
-
// Then setup listeners
|
|
483
|
-
Events.on('time-current-time-changed', this.refresh)
|
|
484
|
-
Events.on('time-range-changed', this.refresh)
|
|
485
|
-
Events.on('time-format-changed', this.refresh)
|
|
486
|
-
Events.on('timeseries-span-changed', this.refresh)
|
|
487
|
-
this.kActivity.$engineEvents.on('forecast-model-changed', this.refresh)
|
|
488
|
-
this.kActivity.$engineEvents.on('selected-level-changed', this.refresh)
|
|
489
|
-
},
|
|
490
|
-
beforeUnmount () {
|
|
491
|
-
// Release listeners
|
|
492
|
-
Events.off('time-current-time-changed', this.refresh)
|
|
493
|
-
Events.off('time-range-changed', this.refresh)
|
|
494
|
-
Events.off('time-format-changed', this.refresh)
|
|
495
|
-
Events.off('timeseries-span-changed', this.refresh)
|
|
496
|
-
this.kActivity.$engineEvents.off('forecast-model-changed', this.refresh)
|
|
497
|
-
this.kActivity.$engineEvents.off('selected-level-changed', this.refresh)
|
|
498
|
-
},
|
|
499
|
-
setup (props) {
|
|
500
|
-
return {
|
|
501
|
-
...useCurrentActivity(),
|
|
502
|
-
...useWeather(),
|
|
503
|
-
...useMeasure(),
|
|
504
|
-
...useHighlight('time-series', props.highlight)
|
|
53
|
+
// Computed
|
|
54
|
+
const hasSingleSerie = computed(() => {
|
|
55
|
+
return state.timeSeries.length === 1
|
|
56
|
+
})
|
|
57
|
+
const hasPinnedSerie = computed(() => {
|
|
58
|
+
return _.find(state.timeSeries, timeSerie => timeSerie.pinned)
|
|
59
|
+
})
|
|
60
|
+
const actions = computed(() => {
|
|
61
|
+
return [{
|
|
62
|
+
id: 'time-serie-logarithmic',
|
|
63
|
+
icon: 'legend_toggle',
|
|
64
|
+
tooltip: 'KTimeSeries.LOGARITHMIC_SERIE_TOOLTIP',
|
|
65
|
+
toggle: { icon: 'legend_toggle', tooltip: 'KTimeSeries.LINEAR_SERIE_TOOLTIP' },
|
|
66
|
+
toggled: ':timeSerie.logarithmic',
|
|
67
|
+
size: 'sm',
|
|
68
|
+
handler: onLogarithmicSerie
|
|
69
|
+
}, {
|
|
70
|
+
id: 'export-time-serie',
|
|
71
|
+
icon: 'las la-file-download',
|
|
72
|
+
tooltip: 'KTimeSeries.EXPORT_SERIE_TOOLTIP',
|
|
73
|
+
size: 'sm',
|
|
74
|
+
handler: onExportData
|
|
75
|
+
}, {
|
|
76
|
+
id: 'pin-time-serie',
|
|
77
|
+
icon: 'las la-thumbtack',
|
|
78
|
+
tooltip: 'KTimeSeries.PIN_SERIE_TOOLTIP',
|
|
79
|
+
size: 'sm',
|
|
80
|
+
visible: (timeSerie) => !hasSingleSerie.value && !hasPinnedSerie.value,
|
|
81
|
+
handler: onPinSerie
|
|
82
|
+
}, {
|
|
83
|
+
id: 'unpin-time-serie',
|
|
84
|
+
icon: 'las la-thumbtack',
|
|
85
|
+
color: 'accent',
|
|
86
|
+
tooltip: 'KTimeSeries.UNPIN_SERIE_TOOLTIP',
|
|
87
|
+
size: 'sm',
|
|
88
|
+
visible: (timeSerie) => isPinned(timeSerie),
|
|
89
|
+
handler: onPinSerie
|
|
90
|
+
}]
|
|
91
|
+
})
|
|
92
|
+
const timeSeries = computed(() => state.timeSeries)
|
|
93
|
+
const isSelectorVisible = computed(() => {
|
|
94
|
+
const visible = Store.get('layout.windows.top.gt.sm')
|
|
95
|
+
return visible && !hasSingleSerie.value
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
// Watch change in time series drivers like time range, format, ...
|
|
99
|
+
watch(Store.get('time.range'), async () => {
|
|
100
|
+
if (chartRef.value) {
|
|
101
|
+
// Reset any zoom
|
|
102
|
+
chartRef.value.resetZoom()
|
|
103
|
+
isZoomed.value = true
|
|
104
|
+
}
|
|
105
|
+
// Update underlying data
|
|
106
|
+
await fetchData()
|
|
107
|
+
// Then graphics
|
|
108
|
+
updateChart()
|
|
109
|
+
})
|
|
110
|
+
watch([Store.get('time.format'), Store.get('units.default')], () => {
|
|
111
|
+
// Update graphics
|
|
112
|
+
updateChart()
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
// Functions
|
|
116
|
+
async function fetchData () {
|
|
117
|
+
if (!chartRef.value) return
|
|
118
|
+
const promises = []
|
|
119
|
+
_.forEach(timeSeries.value, timeSerie => {
|
|
120
|
+
_.forEach(timeSerie.series, serie => {
|
|
121
|
+
promises.push(serie.fetch())
|
|
122
|
+
})
|
|
123
|
+
})
|
|
124
|
+
// Need to wait for data before updating
|
|
125
|
+
await Promise.all(promises)
|
|
126
|
+
}
|
|
127
|
+
function updateChart () {
|
|
128
|
+
if (!chartRef.value) return
|
|
129
|
+
chartRef.value.requestUpdate()
|
|
130
|
+
}
|
|
131
|
+
function isPinned (timeSerie) {
|
|
132
|
+
timeSerie = _.find(state.timeSeries, { id: timeSerie.id })
|
|
133
|
+
return timeSerie && timeSerie.pinned
|
|
134
|
+
}
|
|
135
|
+
function pinTimeSerie (timeSerie) {
|
|
136
|
+
// Pinning means showing an additional graph
|
|
137
|
+
const invisibleTimeSerie = state.timeSeries.find(timeSerie => !timeSerie.visible)
|
|
138
|
+
|
|
139
|
+
// Only one graph visible at a time if no pinning
|
|
140
|
+
// Otherwise only one in addition to the pinned one
|
|
141
|
+
// This is managed by pinning action that will hide once pinned
|
|
142
|
+
_.forEach(state.timeSeries, timeSerie => {
|
|
143
|
+
timeSerie.visible = (timeSerie.id === invisibleTimeSerie.id) || timeSerie.pinned
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
function unpinTimeSerie (timeSerie) {
|
|
147
|
+
// Unpinning means hiding the graph
|
|
148
|
+
timeSerie.visible = false
|
|
149
|
+
}
|
|
150
|
+
function onPinSerie (timeSerie) {
|
|
151
|
+
timeSerie = _.find(state.timeSeries, { id: timeSerie.id })
|
|
152
|
+
if (timeSerie) {
|
|
153
|
+
timeSerie.pinned = !timeSerie.pinned
|
|
154
|
+
if (timeSerie.pinned) {
|
|
155
|
+
pinTimeSerie(timeSerie)
|
|
156
|
+
chartRef.value.zoomToData()
|
|
157
|
+
} else {
|
|
158
|
+
unpinTimeSerie(timeSerie)
|
|
159
|
+
chartRef.value.resetZoom()
|
|
505
160
|
}
|
|
506
161
|
}
|
|
507
162
|
}
|
|
163
|
+
function onLogarithmicSerie (timeSerie) {
|
|
164
|
+
timeSerie = _.find(state.timeSeries, { id: timeSerie.id })
|
|
165
|
+
if (timeSerie) timeSerie.logarithmic = !timeSerie.logarithmic
|
|
166
|
+
}
|
|
167
|
+
function onExportData (timeSerie) {
|
|
168
|
+
if (chartRef.value) chartRef.value.exportSeries(timeSerie)
|
|
169
|
+
}
|
|
170
|
+
function onZoomEnd ({ chart, start, end }) {
|
|
171
|
+
isZoomed.value = true
|
|
172
|
+
}
|
|
173
|
+
function onRestoreZoom () {
|
|
174
|
+
isZoomed.value = (chartRef.value ? chartRef.value.restorePreviousZoom() : false)
|
|
175
|
+
}
|
|
176
|
+
function onResized (size) {
|
|
177
|
+
height.value = size.height
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Expose
|
|
181
|
+
defineExpose({
|
|
182
|
+
isZoomed,
|
|
183
|
+
onRestoreZoom
|
|
184
|
+
})
|
|
508
185
|
</script>
|