Skip to content

Commit 8ce0b91

Browse files
committed
wip: Provide a selection manager component - features properties (#1098)
1 parent becb732 commit 8ce0b91

File tree

3 files changed

+69
-15
lines changed

3 files changed

+69
-15
lines changed

map/client/components/selection/KSelectedLayerFeatures.vue

+67-15
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,45 @@
33
:nodes="[root]"
44
node-key="_id"
55
label-key="label"
6-
children-key="features"
7-
default-expand-all
6+
children-key="children"
7+
v-model:expanded="expandedNodes"
88
dense
99
>
1010
<template v-slot:default-header="prop">
1111
<!-- Layer rendering -->
1212
<q-icon v-if="prop.node.icon" :name="prop.node.icon"/>
13-
<KLayerItem v-if="prop.node.name"
13+
<KLayerItem v-if="isLayerNode(prop.node)"
1414
v-bind="$props"
1515
:togglable="false"
1616
:layer="root"
1717
/>
1818
<!-- Features rendering -->
19-
<div v-else class="row fit items-center q-pl-md q-pr-sm no-wrap">
19+
<div v-else-if="prop.node.label" class="row fit items-center q-pl-md q-pr-sm no-wrap">
2020
<div :class="{
2121
'text-primary': root.isVisible,
2222
'text-grey-6': root.isDisabled || !root.isVisible
2323
}"
2424
>
25-
<span v-html="prop.node.label || prop.node._id" />
25+
<span v-html="prop.node.label" />
2626
</div>
27-
<q-space />
27+
<q-space v-if="isFeatureNode(prop.node)"/>
2828
<!-- Features actions -->
29-
<KPanel
29+
<KPanel v-if="isFeatureNode(prop.node)"
3030
:id="`${prop.node.label}-feature-actions`"
3131
:content="featureActions"
3232
:context="prop.node"
3333
/>
3434
</div>
3535
</template>
36+
<!-- Feature properties rendering -->
37+
<template v-slot:default-body="prop">
38+
<KView v-if="isFeaturePropertiesNode(prop.node)"
39+
class="q-pa-md full-width"
40+
:values="prop.node"
41+
:schema="schema"
42+
:separators="true"
43+
/>
44+
</template>
3645
</q-tree>
3746
</template>
3847

@@ -43,6 +52,7 @@ import { ref, computed } from 'vue'
4352
import { useRoute, useRouter } from 'vue-router'
4453
import bbox from '@turf/bbox'
4554
import { Store, i18n } from '../../../../core/client'
55+
import { KView } from '../../../../core/client/components'
4656
import KLayerItem from '../catalog/KLayerItem.vue'
4757
import { useCurrentActivity } from '../../composables/activity.js'
4858
import { getFeatureId, getFeatureLabel } from '../../utils/utils.js'
@@ -60,6 +70,7 @@ const props = defineProps({
6070
const route = useRoute()
6171
const router = useRouter()
6272
const { CurrentActivity } = useCurrentActivity()
73+
const expandedNodes = ref([props.item.layer._id])
6374
const editedFeatures = ref([])
6475
6576
// Computed
@@ -125,19 +136,60 @@ const featureActions = computed(() => {
125136
}]
126137
}]
127138
})
139+
const schema = computed(() => {
140+
let schema
141+
// Is there any schema ?
142+
if (_.has(props.item.layer, 'schema.content')) {
143+
// As we update the schema does not alter the original one
144+
schema = _.cloneDeep(_.get(props.item.layer, 'schema.content'))
145+
} else {
146+
schema = generatePropertiesSchema(_.get(props.item, 'features[0]', {}), props.item.layer.name)
147+
}
148+
// Ensure schema is not empty
149+
if (_.isNil(schema) || _.isEmpty(_.get(schema, 'properties', {}))) {
150+
return
151+
}
152+
return schema
153+
})
128154
const root = computed(() => {
129-
const features = props.item.features.map(feature => Object.assign({
130-
label: getFeatureLabel(feature, props.item.layer),
131-
icon: (editedFeatures.value.contains(feature) ? 'las la-edit' : '')
132-
}, feature))
155+
const children = props.item.features.map(feature => Object.assign({
156+
icon: getIcon(feature),
157+
label: getLabel(feature),
158+
children: [Object.assign({
159+
icon: getIcon(feature.properties),
160+
label: getLabel(feature.properties)
161+
}, feature.properties)] // Properties only for node displaying it
162+
}, feature)) // Target feature is required as context for actions
163+
// For each feature add a node containing
133164
// Replace default layer actions with new ones
134-
const root = Object.assign({
135-
icon: (editedFeatures.value.length > 0 ? 'las la-edit' : '')
136-
}, _.omit(props.item.layer, ['icon', 'actions']), { actions: layerActions.value, features })
137-
return root
165+
return Object.assign({
166+
icon: getIcon(props.item.layer),
167+
label: getLabel(props.item.layer),
168+
}, _.omit(props.item.layer, ['icon', 'actions']), { actions: layerActions.value, children })
138169
})
139170
140171
// Functions
172+
function isLayerNode (node) {
173+
return node.name
174+
}
175+
function isFeatureNode (node) {
176+
return node.properties
177+
}
178+
function isFeaturePropertiesNode (node) {
179+
return !node.properties && !isLayerNode(node)
180+
}
181+
function getIcon (node) {
182+
if (isLayerNode(node)) return (editedFeatures.value.length > 0 ? 'las la-edit' : '')
183+
if (isFeatureNode(node)) return (editedFeatures.value.contains(node) ? 'las la-edit' : '')
184+
if (isFeaturePropertiesNode(node)) return 'las la-address-card'
185+
return ''
186+
}
187+
function getLabel (node) {
188+
if (isLayerNode(node)) return node.label || node.name
189+
if (isFeatureNode(node)) return getFeatureLabel(node, props.item.layer) || getFeatureId(node, props.item.layer)
190+
if (isFeaturePropertiesNode(node)) return i18n.t('KSelectedLayerFeatures.FEATURE_PROPERTIES_LABEL')
191+
return ''
192+
}
141193
function zoomToSelectedFeatures () {
142194
CurrentActivity.value.zoomToBBox(bbox({ type: 'FeatureCollection', features: props.item.features }))
143195
}

map/client/i18n/map_en.json

+1
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@
522522
"NONE_SELECTED": "Nothing selected"
523523
},
524524
"KSelectedLayerFeatures": {
525+
"FEATURE_PROPERTIES_LABEL": "Feature properties",
525526
"ZOOM_TO_FEATURES_LABEL": "Zoom to layer features",
526527
"EDIT_FEATURES_LABEL": "Edit layer elements",
527528
"REMOVE_FEATURES_LABEL": "Remove layer features",

map/client/i18n/map_fr.json

+1
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,7 @@
521521
"NONE_SELECTED": "Pas de sélection"
522522
},
523523
"KSelectedLayerFeatures": {
524+
"FEATURE_PROPERTIES_LABEL": "Propriétés de l'élément",
524525
"ZOOM_TO_FEATURES_LABEL": "Zoomer sur les éléments de la couche",
525526
"EDIT_FEATURES_LABEL": "Editer les éléments de la couche",
526527
"REMOVE_FEATURES_LABEL": "Supprimer les éléments de la couche",

0 commit comments

Comments
 (0)