@kalisio/kdk 2.1.9 → 2.2.1
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 +7 -2
- 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/KModal.vue +1 -1
- 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 +47 -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 +25 -19
- 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 +147 -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 +150 -5
- 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/icons/wind-speed-0.svg +8 -0
- package/extras/icons/wind-speed-10.svg +8 -0
- package/extras/icons/wind-speed-100.svg +12 -0
- package/extras/icons/wind-speed-105.svg +13 -0
- package/extras/icons/wind-speed-15.svg +9 -0
- package/extras/icons/wind-speed-20.svg +9 -0
- package/extras/icons/wind-speed-25.svg +10 -0
- package/extras/icons/wind-speed-30.svg +10 -0
- package/extras/icons/wind-speed-35.svg +11 -0
- package/extras/icons/wind-speed-40.svg +11 -0
- package/extras/icons/wind-speed-45.svg +12 -0
- package/extras/icons/wind-speed-5.svg +9 -0
- package/extras/icons/wind-speed-50.svg +9 -0
- package/extras/icons/wind-speed-55.svg +10 -0
- package/extras/icons/wind-speed-60.svg +10 -0
- package/extras/icons/wind-speed-65.svg +11 -0
- package/extras/icons/wind-speed-70.svg +11 -0
- package/extras/icons/wind-speed-75.svg +12 -0
- package/extras/icons/wind-speed-80.svg +12 -0
- package/extras/icons/wind-speed-85.svg +13 -0
- package/extras/icons/wind-speed-90.svg +13 -0
- package/extras/icons/wind-speed-95.svg +14 -0
- 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 +65 -21
- 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 +4 -0
- package/map/client/cesium/utils/utils.events.js +30 -0
- package/map/client/cesium/utils/utils.features.js +8 -0
- package/map/client/cesium/utils/utils.popup.js +17 -0
- package/map/client/cesium/utils/utils.style.js +137 -0
- 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 +288 -454
- 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 -24
- package/map/client/components/catalog/KAddLayer.vue +3 -4
- package/map/client/components/catalog/KConnectLayer.vue +20 -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 +6 -2
- package/map/client/components/legend/KLayerLegend.vue +71 -0
- package/map/client/components/legend/KLegend.vue +54 -51
- 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/KLocationCardSection.vue +8 -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 -29
- package/map/client/composables/activity.js +15 -2
- package/map/client/composables/catalog.js +81 -0
- package/map/client/composables/highlight.js +45 -30
- package/map/client/composables/index.js +2 -0
- package/map/client/composables/location.js +25 -18
- package/map/client/composables/probe.js +4 -1
- package/map/client/composables/project.js +122 -0
- package/map/client/composables/weather.js +3 -3
- package/map/client/geolocation.js +1 -1
- package/map/client/globe.js +2 -0
- package/map/client/i18n/map_en.json +127 -76
- package/map/client/i18n/map_fr.json +128 -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 +51 -0
- package/map/client/leaflet/TiledFeatureLayer.js +39 -9
- package/map/client/leaflet/TiledMeshLayer.js +13 -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 +195 -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 +39 -18
- package/map/client/mixins/globe/mixin.geojson-layers.js +139 -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 +53 -28
- 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 +60 -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 +71 -192
- 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 +66 -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 +166 -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 +175 -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 +309 -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/map/common/wms-utils.js +8 -3
- 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 +24 -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/cesium/utils.js +0 -133
- 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
|
@@ -1,77 +1,77 @@
|
|
|
1
1
|
module.exports = [{
|
|
2
|
-
target: '#
|
|
2
|
+
target: '#timecontrols',
|
|
3
3
|
title: 'tours.timeline.TIMELINE_LABEL',
|
|
4
4
|
params: {
|
|
5
5
|
placement: 'top'
|
|
6
6
|
}
|
|
7
7
|
}, {
|
|
8
|
-
target: '#
|
|
8
|
+
target: '#datetime-controls',
|
|
9
9
|
title: 'tours.timeline.DATE_LABEL',
|
|
10
10
|
params: {
|
|
11
11
|
placement: 'top'
|
|
12
12
|
}
|
|
13
13
|
}, {
|
|
14
|
-
target: '#
|
|
15
|
-
title: 'tours.timeline.
|
|
14
|
+
target: '#date-button',
|
|
15
|
+
title: 'tours.timeline.PICK_DAY_LABEL',
|
|
16
16
|
params: {
|
|
17
|
-
placement: 'top'
|
|
17
|
+
placement: 'top',
|
|
18
|
+
clickOn: '#date-button',
|
|
19
|
+
clickDelay: 100
|
|
18
20
|
}
|
|
19
21
|
}, {
|
|
20
|
-
target: '#
|
|
21
|
-
title: 'tours.timeline.
|
|
22
|
-
link: 'tours.timeline.SETTINGS_LINK_LABEL',
|
|
22
|
+
target: '#time-button',
|
|
23
|
+
title: 'tours.timeline.PICK_TIMES_LABEL',
|
|
23
24
|
params: {
|
|
24
25
|
placement: 'top',
|
|
25
|
-
|
|
26
|
+
clickOn: '#time-button',
|
|
27
|
+
clickDelay: 100
|
|
26
28
|
}
|
|
27
29
|
}, {
|
|
28
|
-
target: '#
|
|
29
|
-
title: 'tours.timeline.
|
|
30
|
-
link: 'tours.timeline.SETTINGS_LINK_LABEL',
|
|
30
|
+
target: '#timecontrol-now',
|
|
31
|
+
title: 'tours.timeline.NOW_LABEL',
|
|
31
32
|
params: {
|
|
32
|
-
placement: 'top'
|
|
33
|
-
tour: 'home'
|
|
33
|
+
placement: 'top'
|
|
34
34
|
}
|
|
35
35
|
}, {
|
|
36
|
-
target: '#
|
|
37
|
-
title: 'tours.timeline.
|
|
36
|
+
target: '#timecontrol-step',
|
|
37
|
+
title: 'tours.timeline.STEP_LABEL',
|
|
38
38
|
params: {
|
|
39
|
-
placement: 'top'
|
|
39
|
+
placement: 'top',
|
|
40
40
|
}
|
|
41
41
|
}, {
|
|
42
|
-
target: '#
|
|
43
|
-
title: 'tours.timeline.
|
|
42
|
+
target: '#previous-step',
|
|
43
|
+
title: 'tours.timeline.PREVIOUS_STEP_LABEL',
|
|
44
44
|
params: {
|
|
45
|
-
placement: 'top'
|
|
45
|
+
placement: 'top',
|
|
46
46
|
}
|
|
47
47
|
}, {
|
|
48
|
-
target: '#
|
|
48
|
+
target: '#previous-hour',
|
|
49
49
|
title: 'tours.timeline.PREVIOUS_HOUR_LABEL',
|
|
50
50
|
params: {
|
|
51
|
-
placement: 'top'
|
|
51
|
+
placement: 'top',
|
|
52
52
|
}
|
|
53
53
|
}, {
|
|
54
|
-
target: '#
|
|
55
|
-
title: 'tours.timeline.
|
|
54
|
+
target: '#previous-day',
|
|
55
|
+
title: 'tours.timeline.PREVIOUS_DAY_LABEL',
|
|
56
56
|
params: {
|
|
57
|
-
placement: 'top'
|
|
57
|
+
placement: 'top',
|
|
58
58
|
}
|
|
59
59
|
}, {
|
|
60
|
-
target: '#
|
|
60
|
+
target: '#next-day',
|
|
61
61
|
title: 'tours.timeline.NEXT_DAY_LABEL',
|
|
62
62
|
params: {
|
|
63
|
-
placement: 'top'
|
|
63
|
+
placement: 'top',
|
|
64
64
|
}
|
|
65
65
|
}, {
|
|
66
|
-
target: '#
|
|
67
|
-
title: 'tours.timeline.
|
|
66
|
+
target: '#next-hour',
|
|
67
|
+
title: 'tours.timeline.NEXT_HOUR_LABEL',
|
|
68
68
|
params: {
|
|
69
|
-
placement: 'top'
|
|
69
|
+
placement: 'top',
|
|
70
70
|
}
|
|
71
71
|
}, {
|
|
72
|
-
target: '#
|
|
73
|
-
title: 'tours.timeline.
|
|
72
|
+
target: '#next-step',
|
|
73
|
+
title: 'tours.timeline.NEXT_STEP_LABEL',
|
|
74
74
|
params: {
|
|
75
|
-
placement: 'top'
|
|
75
|
+
placement: 'top',
|
|
76
76
|
}
|
|
77
77
|
}]
|
|
@@ -21,7 +21,10 @@ module.exports = function (categoryFiles, context) {
|
|
|
21
21
|
categories = categories.concat(categoriesFromFile)
|
|
22
22
|
})
|
|
23
23
|
debug(`Found ${categories.length} category definitions to build catalog from`)
|
|
24
|
-
|
|
24
|
+
// Sort categories
|
|
25
|
+
categories.sort((category, other) => {
|
|
26
|
+
return (category.order || 50) - (other.order || 50)
|
|
27
|
+
})
|
|
25
28
|
// All categories by default
|
|
26
29
|
let filter = categories.map(category => category.name.replace('Categories.', ''))
|
|
27
30
|
// Now build filter according any env filter
|
|
@@ -83,3 +83,42 @@ export async function updateLayerReferences (hook) {
|
|
|
83
83
|
debug(`Updated ${contexts.length} contexts and categories after renaming or removing layer ${layer.name} `)
|
|
84
84
|
return hook
|
|
85
85
|
}
|
|
86
|
+
|
|
87
|
+
// Update projects when a layer/view is removed
|
|
88
|
+
export async function updateProjects (hook) {
|
|
89
|
+
const app = hook.app
|
|
90
|
+
const context = hook.service.getContextId()
|
|
91
|
+
const projectsService = app.getService('projects', context)
|
|
92
|
+
if (!projectsService) return hook
|
|
93
|
+
let removedItems = getItems(hook)
|
|
94
|
+
if (!Array.isArray(removedItems)) removedItems = [removedItems]
|
|
95
|
+
for (let i = 0; i < removedItems.length; i++) {
|
|
96
|
+
const removedItem = removedItems[i]
|
|
97
|
+
const isLayer = removedItem.type !== 'Context'
|
|
98
|
+
const query = {}
|
|
99
|
+
if (isLayer) {
|
|
100
|
+
query.$or = [{ 'layers._id': removedItem._id }, { 'layers.name': removedItem.name }]
|
|
101
|
+
} else {
|
|
102
|
+
query['views._id'] = removedItem._id
|
|
103
|
+
}
|
|
104
|
+
// Retrieve the list of all projects involving the item
|
|
105
|
+
const projects = await projectsService.find({
|
|
106
|
+
query, paginate: false
|
|
107
|
+
})
|
|
108
|
+
// Stop when non found
|
|
109
|
+
if (projects.length === 0) {
|
|
110
|
+
debug(`No project to update after removing item ${removedItem.name} `)
|
|
111
|
+
return hook
|
|
112
|
+
}
|
|
113
|
+
// Update each project otherwise
|
|
114
|
+
await Promise.all(projects.map(project => {
|
|
115
|
+
// Remove item in list
|
|
116
|
+
const items = (isLayer ? project.layers : project.views)
|
|
117
|
+
_.remove(items, item => item._id ? removedItem._id.toString() === item._id.toString() : removedItem.name === item.name)
|
|
118
|
+
return projectsService.patch(project._id.toString(), isLayer ? { layers: items } : { views: items })
|
|
119
|
+
}))
|
|
120
|
+
|
|
121
|
+
debug(`Updated ${projects.length} projects after removing item ${removedItem.name} `)
|
|
122
|
+
}
|
|
123
|
+
return hook
|
|
124
|
+
}
|
|
@@ -4,6 +4,7 @@ import bbox from '@turf/bbox'
|
|
|
4
4
|
import makeDebug from 'debug'
|
|
5
5
|
import feathers from '@feathersjs/feathers'
|
|
6
6
|
import common from 'feathers-hooks-common'
|
|
7
|
+
import mongodbFuzzySearch from 'feathers-mongodb-fuzzy-search'
|
|
7
8
|
import { hooks as coreHooks, unmarshallTime } from '../../../core/api/index.js'
|
|
8
9
|
|
|
9
10
|
const { defaultEventMap } = feathers
|
|
@@ -31,12 +32,16 @@ function getLayers (features) {
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
export function simplifyResult (hook) {
|
|
35
|
+
// Force full result emission ?
|
|
36
|
+
const fullResult = _.get(hook, 'params.fullResult')
|
|
37
|
+
if (fullResult) return hook
|
|
34
38
|
const service = hook.service
|
|
35
39
|
const method = hook.method
|
|
36
40
|
const result = getItems(hook)
|
|
37
41
|
const simplifyResult = _.get(service, 'options.simplifyResult', ['create', 'update', 'patch', 'remove'])
|
|
42
|
+
const simplifyResultLimit = _.get(service, 'options.simplifyResultLimit', 1)
|
|
38
43
|
// Only keep track of object IDs so that caller can at least get them if required
|
|
39
|
-
if (simplifyResult.includes(method) && Array.isArray(result)) {
|
|
44
|
+
if (simplifyResult.includes(method) && Array.isArray(result) && (result.length > simplifyResultLimit)) {
|
|
40
45
|
debug(`Simplifying multi result for ${method} method on service ${service.name}`)
|
|
41
46
|
replaceItems(hook, result.map(item => ({ _id: item._id })))
|
|
42
47
|
}
|
|
@@ -44,6 +49,9 @@ export function simplifyResult (hook) {
|
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
export function skipEvents (hook) {
|
|
52
|
+
// Force standard event emission ?
|
|
53
|
+
const emitEvents = _.get(hook, 'params.emitEvents')
|
|
54
|
+
if (emitEvents) return hook
|
|
47
55
|
const service = hook.service
|
|
48
56
|
const method = hook.method
|
|
49
57
|
const event = defaultEventMap[method]
|
|
@@ -52,12 +60,16 @@ export function skipEvents (hook) {
|
|
|
52
60
|
const simplifyEvents = _.get(service, 'options.simplifyEvents', [])
|
|
53
61
|
// Even if we emit simplified events we skip standard feathers events to emit our own version
|
|
54
62
|
let skip = skipEvents.includes(event) || simplifyEvents.includes(event)
|
|
55
|
-
|
|
63
|
+
const skipEventsLimit = _.get(service, 'options.skipEventsLimit', 1)
|
|
64
|
+
skip = skip && Array.isArray(result) && (result.length > skipEventsLimit)
|
|
56
65
|
if (skip) debug(`Skipping standard event ${event} for multi operation on service ${service.name}`)
|
|
57
66
|
return iff(hook => skip, coreHooks.skipEvents)(hook)
|
|
58
67
|
}
|
|
59
68
|
|
|
60
69
|
export function simplifyEvents (hook) {
|
|
70
|
+
// Force standard event emission ?
|
|
71
|
+
const emitEvents = _.get(hook, 'params.emitEvents')
|
|
72
|
+
if (emitEvents) return hook
|
|
61
73
|
const service = hook.service
|
|
62
74
|
const params = hook.params
|
|
63
75
|
const data = hook.data
|
|
@@ -67,7 +79,8 @@ export function simplifyEvents (hook) {
|
|
|
67
79
|
const event = defaultEventMap[method]
|
|
68
80
|
const result = getItems(hook)
|
|
69
81
|
const simplifyEvents = _.get(service, 'options.simplifyEvents', [])
|
|
70
|
-
|
|
82
|
+
const simplifyEventsLimit = _.get(service, 'options.simplifyEventsLimit', 1)
|
|
83
|
+
if (simplifyEvents.includes(event) && Array.isArray(result) && (result.length > simplifyEventsLimit)) {
|
|
71
84
|
debug(`Simplifying event ${event} for multi operation on service ${service.name}`)
|
|
72
85
|
// Keep track of query selector when updating/patching/removing in batch
|
|
73
86
|
const payload = (event === 'created' ? {} : { data })
|
|
@@ -82,3 +95,10 @@ export function simplifyEvents (hook) {
|
|
|
82
95
|
}
|
|
83
96
|
return hook
|
|
84
97
|
}
|
|
98
|
+
|
|
99
|
+
export function fuzzySearch (hook) {
|
|
100
|
+
const service = hook.service
|
|
101
|
+
const featureLabel = _.castArray(_.get(service, 'options.featureLabel', []))
|
|
102
|
+
const fields = featureLabel.map((prop) => 'properties.' + prop)
|
|
103
|
+
return featureLabel.length ? mongodbFuzzySearch({ fields: fields })(hook) : hook
|
|
104
|
+
}
|
|
@@ -12,6 +12,35 @@ export function marshallGeometryQuery (hook) {
|
|
|
12
12
|
marshallGeometry(geometry)
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
function getGeometryQueryForBBox (bbox) {
|
|
16
|
+
// Here we use the custom MongoDB CRS that enforces counter-clockwise winding order
|
|
17
|
+
// and allows to support queries with a single-ringed GeoJSON polygon
|
|
18
|
+
// whose area is greater than or equal to a single hemisphere.
|
|
19
|
+
// Otherwise $geoIntersects queries for the complementary geometry.
|
|
20
|
+
return {
|
|
21
|
+
$geoIntersects: {
|
|
22
|
+
$geometry: {
|
|
23
|
+
type: 'Polygon',
|
|
24
|
+
coordinates: [bbox],
|
|
25
|
+
crs: {
|
|
26
|
+
type: 'name',
|
|
27
|
+
properties: { name: 'urn:x-mongodb:crs:strictwinding:EPSG:4326' }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function marshallGeoJsonQuery (hook) {
|
|
35
|
+
const query = hook.params.query
|
|
36
|
+
if (query) {
|
|
37
|
+
if (query.geoJson) {
|
|
38
|
+
delete query.geoJson
|
|
39
|
+
hook.params.asGeoJson = true
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
15
44
|
export function marshallSpatialQuery (hook) {
|
|
16
45
|
const query = hook.params.query
|
|
17
46
|
if (query) {
|
|
@@ -66,17 +95,20 @@ export function marshallSpatialQuery (hook) {
|
|
|
66
95
|
delete query.north
|
|
67
96
|
delete query.west
|
|
68
97
|
delete query.east
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
98
|
+
|
|
99
|
+
// FIXME: MongoDB should allow to support queries with a single-ringed GeoJSON polygon
|
|
100
|
+
// whose area is greater than or equal to a single hemisphere.
|
|
101
|
+
// However, we did not succeeed in making it work as expected, for now on we split large polygon into two halfs.
|
|
102
|
+
if ((east-west) <= 180) {
|
|
103
|
+
// BBox as a polygon also requires the closing point.
|
|
104
|
+
const bbox = [[west, south], [east, south], [east, north], [west, north], [west, south]]
|
|
105
|
+
query.geometry = getGeometryQueryForBBox(bbox)
|
|
106
|
+
} else {
|
|
107
|
+
// BBox as a polygon also requires the closing point.
|
|
108
|
+
const leftHalfBbox = [[west, south], [0.5*(west+east), south], [0.5*(west+east), north], [west, north], [west, south]]
|
|
109
|
+
const rightHalfBbox = [[0.5*(west+east), south], [east, south], [east, north], [0.5*(west+east), north], [0.5*(west+east), south]]
|
|
110
|
+
query.$or = [{ geometry: getGeometryQueryForBBox(leftHalfBbox) }, { geometry: getGeometryQueryForBBox(rightHalfBbox) }]
|
|
78
111
|
}
|
|
79
|
-
query.geometry = geometryQuery
|
|
80
112
|
}
|
|
81
113
|
// Shortcut for location query
|
|
82
114
|
if (!_.isNil(query.longitude) && !_.isNil(query.latitude)) {
|
|
@@ -95,11 +127,9 @@ export function marshallSpatialQuery (hook) {
|
|
|
95
127
|
}
|
|
96
128
|
query.geometry = geometryQuery
|
|
97
129
|
}
|
|
98
|
-
if (query.geoJson) {
|
|
99
|
-
delete query.geoJson
|
|
100
|
-
hook.params.asGeoJson = true
|
|
101
|
-
}
|
|
102
130
|
}
|
|
131
|
+
// Include GeoJson query by default
|
|
132
|
+
marshallGeoJsonQuery(hook)
|
|
103
133
|
}
|
|
104
134
|
|
|
105
135
|
export function asGeoJson (options = {}) {
|
|
@@ -118,6 +148,9 @@ export function asGeoJson (options = {}) {
|
|
|
118
148
|
const isPaginated = !_.isNil(results.data)
|
|
119
149
|
const pagination = (isPaginated ? _.pick(results, ['total', 'skip', 'limit']) : {})
|
|
120
150
|
results = (isPaginated ? results.data : results)
|
|
151
|
+
// Single item case, i.e. GET ?
|
|
152
|
+
const isFeatureCollection = Array.isArray(results)
|
|
153
|
+
if (!isFeatureCollection) results = [results]
|
|
121
154
|
results = results
|
|
122
155
|
.filter(item => {
|
|
123
156
|
// Check if item is not already in GeoJson feature format and we can convert if required
|
|
@@ -169,24 +202,35 @@ export function asGeoJson (options = {}) {
|
|
|
169
202
|
// Move some data to properties ?
|
|
170
203
|
if (options.properties) {
|
|
171
204
|
results.forEach(item => {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
205
|
+
// True indicates to move all fields to properties
|
|
206
|
+
if (options.properties === true) {
|
|
207
|
+
_.forOwn(item, (value, key) => {
|
|
208
|
+
if ((key === 'geometry') || (key === 'type') || (key === '_id')) return
|
|
209
|
+
_.set(item, `properties.${key}`, _.get(item, key))
|
|
210
|
+
_.unset(item, key)
|
|
211
|
+
})
|
|
212
|
+
} else { // Else we expect a specific mapping
|
|
213
|
+
options.properties.forEach(mapping => {
|
|
214
|
+
if (mapping.from) _.set(item, `properties.${mapping.to || mapping.from}`, _.get(item, `${mapping.from}`))
|
|
215
|
+
if (mapping.delete) _.unset(item, `${mapping.from}`)
|
|
216
|
+
})
|
|
217
|
+
}
|
|
176
218
|
})
|
|
177
219
|
}
|
|
178
|
-
//
|
|
179
|
-
if (_.get(options, 'asFeatureCollection', true)) {
|
|
220
|
+
// If we should make it available as a GeoJson feature collection create it
|
|
221
|
+
if (isFeatureCollection && _.get(options, 'asFeatureCollection', true)) {
|
|
222
|
+
// Copy pagination information if any so that client can use it anyway
|
|
180
223
|
_.set(hook, options.dataPath || 'result', Object.assign({
|
|
181
224
|
type: 'FeatureCollection',
|
|
182
225
|
features: results
|
|
183
226
|
}, pagination)) // If no pagination this merged object will be empty
|
|
184
227
|
} else if (isPaginated) {
|
|
228
|
+
// Copy pagination information if any so that client can use it anyway
|
|
185
229
|
_.set(hook, options.dataPath || 'result', Object.assign({
|
|
186
230
|
data: results
|
|
187
231
|
}, pagination))
|
|
188
232
|
} else {
|
|
189
|
-
_.set(hook, options.dataPath || 'result', results)
|
|
233
|
+
_.set(hook, options.dataPath || 'result', isFeatureCollection ? results : results[0])
|
|
190
234
|
}
|
|
191
235
|
}
|
|
192
236
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export default function (app, options) {
|
|
2
|
+
const db = options.db || app.db
|
|
3
|
+
options.Model = db.collection('projects')
|
|
4
|
+
// Collation provided in query ensure sorting to be case insensitive w.r.t. user's language
|
|
5
|
+
// We built indices with collation to cover the most used languages, it requires different naming...
|
|
6
|
+
options.Model.createIndex({ name: 1 }, { name: 'name-en', collation: { locale: 'en', strength: 1 } })
|
|
7
|
+
options.Model.createIndex({ name: 1 }, { name: 'name-fr', collation: { locale: 'fr', strength: 1 } })
|
|
8
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
2
|
import common from 'feathers-hooks-common'
|
|
3
|
+
import fuzzySearch from 'feathers-mongodb-fuzzy-search'
|
|
3
4
|
import { hooks as coreHooks } from '../../../../core/api/index.js'
|
|
4
|
-
import { filterLayers, updateLayerReferences, getDefaultCategories, getDefaultSublegends } from '../../hooks/index.js'
|
|
5
|
+
import { filterLayers, updateLayerReferences, updateProjects, getDefaultCategories, getDefaultSublegends } from '../../hooks/index.js'
|
|
5
6
|
|
|
6
7
|
const { setNow, discard } = common
|
|
7
8
|
|
|
@@ -9,7 +10,7 @@ export default {
|
|
|
9
10
|
before: {
|
|
10
11
|
all: [],
|
|
11
12
|
find: [
|
|
12
|
-
filterLayers, coreHooks.distinct
|
|
13
|
+
fuzzySearch({ fields: ['name'] }), coreHooks.diacriticSearch(), filterLayers, coreHooks.distinct
|
|
13
14
|
],
|
|
14
15
|
get: [],
|
|
15
16
|
create: [
|
|
@@ -60,7 +61,8 @@ export default {
|
|
|
60
61
|
],
|
|
61
62
|
remove: [
|
|
62
63
|
setNow('updatedAt'),
|
|
63
|
-
updateLayerReferences
|
|
64
|
+
updateLayerReferences,
|
|
65
|
+
updateProjects
|
|
64
66
|
]
|
|
65
67
|
},
|
|
66
68
|
|
|
@@ -1,19 +1,31 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
1
2
|
import { hooks as coreHooks } from '../../../../core/api/index.js'
|
|
2
3
|
import {
|
|
3
4
|
marshallSpatialQuery, aggregateFeaturesQuery, asGeoJson,
|
|
4
|
-
simplifyResult, simplifyEvents, skipEvents
|
|
5
|
+
simplifyResult, simplifyEvents, skipEvents, fuzzySearch
|
|
5
6
|
} from '../../hooks/index.js'
|
|
6
7
|
|
|
8
|
+
// Allow to control real-time events emission if required
|
|
9
|
+
const emitEvents = (hook) => {
|
|
10
|
+
_.set(hook, 'params.emitEvents', _.get(hook, 'params.query.emitEvents'))
|
|
11
|
+
_.unset(hook, 'params.query.emitEvents')
|
|
12
|
+
}
|
|
13
|
+
// Allow to control full result emission if required
|
|
14
|
+
const fullResult = (hook) => {
|
|
15
|
+
_.set(hook, 'params.fullResult', _.get(hook, 'params.query.fullResult'))
|
|
16
|
+
_.unset(hook, 'params.query.fullResult')
|
|
17
|
+
}
|
|
18
|
+
|
|
7
19
|
export default {
|
|
8
20
|
before: {
|
|
9
21
|
all: [coreHooks.marshallTimeQuery, coreHooks.convertObjectIDs(['layer'])],
|
|
10
22
|
find: [coreHooks.marshallComparisonQuery, coreHooks.marshallSortQuery, marshallSpatialQuery,
|
|
11
|
-
coreHooks.distinct, aggregateFeaturesQuery, coreHooks.aggregationQuery],
|
|
23
|
+
coreHooks.distinct, aggregateFeaturesQuery, coreHooks.aggregationQuery, fuzzySearch, coreHooks.diacriticSearch],
|
|
12
24
|
get: [],
|
|
13
|
-
create: [coreHooks.processTimes(['time'])],
|
|
14
|
-
update: [coreHooks.processTimes(['time'])],
|
|
15
|
-
patch: [coreHooks.processTimes(['time'])],
|
|
16
|
-
remove: [coreHooks.marshallComparisonQuery, marshallSpatialQuery]
|
|
25
|
+
create: [coreHooks.processTimes(['time']), fullResult, emitEvents],
|
|
26
|
+
update: [coreHooks.processTimes(['time']), fullResult, emitEvents],
|
|
27
|
+
patch: [coreHooks.processTimes(['time']), fullResult, emitEvents],
|
|
28
|
+
remove: [coreHooks.marshallComparisonQuery, marshallSpatialQuery, fullResult, emitEvents]
|
|
17
29
|
},
|
|
18
30
|
|
|
19
31
|
after: {
|
|
@@ -18,7 +18,7 @@ export function createFeaturesService (options = {}) {
|
|
|
18
18
|
|
|
19
19
|
debug('Creating features service with options', options)
|
|
20
20
|
return app.createService(options.collection, Object.assign({
|
|
21
|
-
|
|
21
|
+
modelName: 'features',
|
|
22
22
|
servicesPath,
|
|
23
23
|
modelsPath,
|
|
24
24
|
paginate: { default: 5000, max: 5000 },
|
|
@@ -50,6 +50,22 @@ export function removeCatalogService (options = {}) {
|
|
|
50
50
|
return app.removeService(app.getService('catalog', options.context))
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
export async function createProjectsService (options = {}) {
|
|
54
|
+
const app = this
|
|
55
|
+
|
|
56
|
+
debug('Creating projects service with options', options)
|
|
57
|
+
await app.createService('projects', Object.assign({
|
|
58
|
+
servicesPath,
|
|
59
|
+
modelsPath,
|
|
60
|
+
paginate: { default: 20, max: 5000 }
|
|
61
|
+
}, options))
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function removeProjectsService (options = {}) {
|
|
65
|
+
const app = this
|
|
66
|
+
return app.removeService(app.getService('projects', options.context))
|
|
67
|
+
}
|
|
68
|
+
|
|
53
69
|
export function createAlertsService (options = {}) {
|
|
54
70
|
const app = this
|
|
55
71
|
|
|
@@ -126,13 +142,13 @@ export async function createDefaultCatalogLayers (options) {
|
|
|
126
142
|
featuresService = await createFeaturesServiceForLayer.call(app, Object.assign({
|
|
127
143
|
collection: defaultLayer.service,
|
|
128
144
|
db: app.db.db(defaultLayer.dbName)
|
|
129
|
-
}, _.pick(defaultLayer, ['ttl', 'featureId', 'featureIdType', 'variables', 'simplifyResult', 'skipEvents', 'simplifyEvents'])))
|
|
145
|
+
}, _.pick(defaultLayer, ['ttl', 'featureId', 'featureIdType', 'featureLabel', 'variables', 'simplifyResult', 'skipEvents', 'simplifyEvents'])))
|
|
130
146
|
}
|
|
131
147
|
if (defaultLayer.probeService) {
|
|
132
148
|
await createFeaturesServiceForLayer.call(app, Object.assign({
|
|
133
149
|
collection: defaultLayer.probeService,
|
|
134
150
|
db: app.db.db(defaultLayer.dbName)
|
|
135
|
-
}, _.pick(defaultLayer, ['simplifyResult', 'skipEvents', 'simplifyEvents'])))
|
|
151
|
+
}, _.pick(defaultLayer, ['featureLabel', 'simplifyResult', 'skipEvents', 'simplifyEvents'])))
|
|
136
152
|
}
|
|
137
153
|
// And if we need to initialize some data as well
|
|
138
154
|
if (!createdLayer && featuresService && (defaultLayer.url || defaultLayer.fileName)) {
|
|
@@ -183,9 +199,9 @@ export default async function () {
|
|
|
183
199
|
if (catalogConfig) {
|
|
184
200
|
await createCatalogService.call(app)
|
|
185
201
|
}
|
|
186
|
-
const
|
|
187
|
-
if (
|
|
188
|
-
await
|
|
202
|
+
const projectsConfig = app.get('projects')
|
|
203
|
+
if (projectsConfig) {
|
|
204
|
+
await createProjectsService.call(app)
|
|
189
205
|
}
|
|
190
206
|
// Add app-specific hooks to required services
|
|
191
207
|
app.on('service', async service => {
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
2
|
+
import commonHooks from 'feathers-hooks-common'
|
|
3
|
+
// import { hooks as schemaHooks, resolve } from '@feathersjs/schema'
|
|
4
|
+
import { hooks as coreHooks } from '../../../../core/api/index.js'
|
|
5
|
+
|
|
6
|
+
const { setNow, discard, getItems, replaceItems, when } = commonHooks
|
|
7
|
+
|
|
8
|
+
/* Populate is too much specialized and does not allow to merge input/output
|
|
9
|
+
but we need the service information on the fronted
|
|
10
|
+
export const populateLayers = populate({
|
|
11
|
+
schema: hook => {
|
|
12
|
+
const service = hook.app.getService('catalog')
|
|
13
|
+
return {
|
|
14
|
+
include: [{
|
|
15
|
+
service: service.getPath(true),
|
|
16
|
+
nameAs: 'layers',
|
|
17
|
+
select: (hook, project) => ({ _id: { $in: _.map(project.layers, '_id') } })
|
|
18
|
+
}]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/* Can't get resolvers to work
|
|
25
|
+
const layersResolver = resolve({
|
|
26
|
+
layers: async (project, context) => {
|
|
27
|
+
// Populate the layers associated via ids
|
|
28
|
+
const layers = await context.app.getService('catalog').find({ query: { _id: [project.layers] } })
|
|
29
|
+
return layers
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
const contextsResolver = resolve({
|
|
33
|
+
contexts: async (project, context) => {
|
|
34
|
+
// Populate the contexts associated via ids
|
|
35
|
+
const contexts = await context.app.getService('catalog').find({ query: { _id: [project.contexts], type: 'Context' } })
|
|
36
|
+
return contexts
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
function marshallPopulateQuery (hook) {
|
|
42
|
+
const query = hook.params.query
|
|
43
|
+
if (query) {
|
|
44
|
+
if (query.populate) {
|
|
45
|
+
delete query.populate
|
|
46
|
+
hook.params.populate = true
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const populateProjects = async (hook) => {
|
|
52
|
+
let items = getItems(hook)
|
|
53
|
+
const isArray = Array.isArray(items)
|
|
54
|
+
items = (isArray ? items : [items])
|
|
55
|
+
for (let i = 0; i < items.length; i++) {
|
|
56
|
+
const project = items[i]
|
|
57
|
+
const layers = project.layers || []
|
|
58
|
+
for (let j = 0; j < layers.length; j++) {
|
|
59
|
+
let layer = layers[j]
|
|
60
|
+
// Get only name when listing
|
|
61
|
+
const query = { $select: ['name', 'service', 'probeService'] }
|
|
62
|
+
const service = hook.app.getService('catalog', _.has(layer, 'context') ? layer.context : hook.service.context)
|
|
63
|
+
// As we keep track of ID/name depending on if a layer is a user-defined one or not we need to process both
|
|
64
|
+
Object.assign(query, (layer._id ? { _id: layer._id } : { name: layer.name }))
|
|
65
|
+
const response = await service.find({ query })
|
|
66
|
+
layer = _.get(response, 'data[0]')
|
|
67
|
+
Object.assign(layers[j], layer)
|
|
68
|
+
}
|
|
69
|
+
const views = project.views || []
|
|
70
|
+
for (let j = 0; j < views.length; j++) {
|
|
71
|
+
let view = views[j]
|
|
72
|
+
// Get only name when listing
|
|
73
|
+
const query = { $select: ['name'], type: 'Context' }
|
|
74
|
+
Object.assign(query, { _id: view._id })
|
|
75
|
+
const service = hook.app.getService('catalog', _.has(view, 'context') ? view.context : hook.service.context)
|
|
76
|
+
const response = await service.find({ query })
|
|
77
|
+
view = _.get(response, 'data[0]')
|
|
78
|
+
Object.assign(views[j], view)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
replaceItems(hook, isArray ? items : items[0])
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export default {
|
|
85
|
+
before: {
|
|
86
|
+
all: [],
|
|
87
|
+
find: [marshallPopulateQuery],
|
|
88
|
+
get: [marshallPopulateQuery],
|
|
89
|
+
create: [coreHooks.convertObjectIDs(['layers', 'views']), setNow('createdAt', 'updatedAt')],
|
|
90
|
+
update: [],
|
|
91
|
+
patch: [coreHooks.convertObjectIDs(['layers', 'views']), discard('createdAt', 'updatedAt'), setNow('updatedAt')],
|
|
92
|
+
remove: []
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
after: {
|
|
96
|
+
all: [],
|
|
97
|
+
find: [when(hook => hook.params.populate, populateProjects)],
|
|
98
|
+
get: [when(hook => hook.params.populate, populateProjects)],
|
|
99
|
+
create: [],
|
|
100
|
+
update: [],
|
|
101
|
+
patch: [],
|
|
102
|
+
remove: []
|
|
103
|
+
},
|
|
104
|
+
/* Can't get resolvers to work
|
|
105
|
+
around: {
|
|
106
|
+
all: [schemaHooks.resolveResult(layersResolver), schemaHooks.resolveResult(contextsResolver)]
|
|
107
|
+
},
|
|
108
|
+
*/
|
|
109
|
+
error: {
|
|
110
|
+
all: [],
|
|
111
|
+
find: [],
|
|
112
|
+
get: [],
|
|
113
|
+
create: [],
|
|
114
|
+
update: [],
|
|
115
|
+
patch: [],
|
|
116
|
+
remove: [setNow('updatedAt')]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Notify } from 'quasar'
|
|
2
|
+
import { capture } from './utils/utils.capture.js'
|
|
3
|
+
import { i18n } from '../../core/client/index.js'
|
|
4
|
+
|
|
5
|
+
// Export singleton
|
|
6
|
+
export const Capture = {
|
|
7
|
+
processing: false,
|
|
8
|
+
async process (values) {
|
|
9
|
+
if (this.processing) Notify.create({ type: 'negative', message: i18n.t('KCapture.ERROR_MESSAGE') })
|
|
10
|
+
else {
|
|
11
|
+
this.processing = true
|
|
12
|
+
await capture(values)
|
|
13
|
+
this.processing = false
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|