feat: allow to configure the default label keys per instance

fix #2289
This commit is contained in:
Yohan Boniface 2024-11-21 14:20:05 +01:00
parent 401efc037d
commit 78d6699a81
11 changed files with 64 additions and 26 deletions

View file

@ -175,11 +175,6 @@ UMAP_EXTRA_URLS = {
}
```
#### UMAP_KEEP_VERSIONS
How many datalayer versions to keep. 10 by default.
#### UMAP_DEFAULT_EDIT_STATUS
Define the map default edit status.
@ -270,6 +265,16 @@ Available importers:
- `communesfr`: download French communes boundaries, from https://geo.api.gouv.fr/
- `datasets`: define URLs you want to promote to users, with a `name` and a `format`
#### UMAP_KEEP_VERSIONS
How many datalayer versions to keep. 10 by default.
#### UMAP_LABEL_KEYS
List of properties to consider as "Feature label" (to show in popup or in browser).
UMAP_LABEL_KEYS = ["name", "title"]
#### UMAP_MAPS_PER_PAGE
How many maps to show in maps list, like search or home page.

View file

@ -273,6 +273,7 @@ UMAP_HOME_FEED = "latest"
UMAP_IMPORTERS = {}
UMAP_HOST_INFOS = {}
UMAP_PURGATORY_ROOT = "/tmp/umappurgatory"
UMAP_LABEL_KEYS = ["name", "title"]
UMAP_READONLY = env("UMAP_READONLY", default=False)
UMAP_GZIP = True

View file

@ -165,7 +165,9 @@ class Feature {
}
getSlug() {
return this.properties[this._umap.getProperty('slugKey') || 'name'] || ''
return (
this.properties[this._umap.getProperty('slugKey') || U.DEFAULT_LABEL_KEY] || ''
)
}
getPermalink() {
@ -235,14 +237,14 @@ class Feature {
const properties = []
for (const property of this.datalayer._propertiesIndex) {
if (['name', 'description'].includes(property)) {
if ([U.DEFAULT_LABEL_KEY, 'description'].includes(property)) {
continue
}
properties.push([`properties.${property}`, { label: property }])
}
// We always want name and description for now (properties management to come)
properties.unshift('properties.description')
properties.unshift('properties.name')
properties.unshift(`properties.${U.DEFAULT_LABEL_KEY}`)
builder = new U.FormBuilder(this, properties, {
id: 'umap-feature-properties',
})
@ -316,19 +318,22 @@ class Feature {
endEdit() {}
getDisplayName(fallback) {
const key = this.getOption('labelKey') || 'name'
getDisplayName() {
const keys = U.LABEL_KEYS.slice() // Copy.
const labelKey = this.getOption('labelKey')
// Variables mode.
if (Utils.hasVar(key)) {
return Utils.greedyTemplate(key, this.extendedProperties())
if (labelKey) {
if (Utils.hasVar(labelKey)) {
return Utils.greedyTemplate(labelKey, this.extendedProperties())
}
keys.unshift(labelKey)
}
// Simple mode.
return (
this.properties[key] ||
this.properties.title ||
fallback ||
this.datalayer.getName()
)
for (const key of keys) {
const value = this.properties[key]
console.log(key, value)
if (value) return value
}
return this.datalayer.getName()
}
hasPopupFooter() {

View file

@ -289,7 +289,7 @@ export class DataLayer extends ServerStored {
reindex() {
const features = Object.values(this._features)
Utils.sortFeatures(features, this._umap.getProperty('sortKey'), U.lang)
this.sortFeatures(features)
this._index = features.map((feature) => stamp(feature))
}
@ -446,6 +446,11 @@ export class DataLayer extends ServerStored {
}
}
sortFeatures(collection) {
const sortKeys = this._umap.getProperty('sortKey') || U.DEFAULT_LABEL_KEY
return Utils.sortFeatures(collection, sortKeys, U.lang)
}
makeFeatures(geojson = {}, sync = true) {
if (geojson.type === 'Feature' || geojson.coordinates) {
geojson = [geojson]
@ -454,7 +459,7 @@ export class DataLayer extends ServerStored {
? geojson
: geojson.features || geojson.geometries
if (!collection) return
Utils.sortFeatures(collection, this._umap.getProperty('sortKey'), U.lang)
this.sortFeatures(collection)
for (const feature of collection) {
this.makeFeature(feature, sync)
}

View file

@ -115,7 +115,9 @@ class Table extends TitleMixin(PopupTemplate) {
const table = document.createElement('table')
for (const key in feature.properties) {
if (typeof feature.properties[key] === 'object' || key === 'name') continue
if (typeof feature.properties[key] === 'object' || U.LABEL_KEYS.includes(key)) {
continue
}
table.appendChild(this.makeRow(feature, key))
}
return table

View file

@ -75,7 +75,7 @@ const FeatureMixin = {
resetTooltip: function () {
if (!this.feature.hasGeom()) return
const displayName = this.feature.getDisplayName(null)
const displayName = this.feature.getDisplayName()
let showLabel = this.feature.getOption('showLabel')
const oldLabelHover = this.feature.getOption('labelHover')

View file

@ -105,7 +105,7 @@ export default class TableEditor extends WithTemplate {
resetProperties() {
this.properties = this.datalayer._propertiesIndex
if (this.properties.length === 0) {
this.properties = ['name', 'description']
this.properties = [U.DEFAULT_LABEL_KEY, 'description']
}
}

View file

@ -71,6 +71,10 @@ export default class Umap extends ServerStored {
// To be used in javascript APIs
if (geojson.properties.lang) U.lang = geojson.properties.lang
// Make it available to utils, without needing a reference to `Umap`.
U.LABEL_KEYS = geojson.properties.defaultLabelKeys || []
U.DEFAULT_LABEL_KEY = U.LABEL_KEYS[0] || 'name'
this.setPropertiesFromQueryString()
// Needed for actions labels

View file

@ -292,7 +292,7 @@ export function naturalSort(a, b, lang) {
}
export function sortFeatures(features, sortKey, lang) {
const sortKeys = (sortKey || 'name').split(',')
const sortKeys = sortKey.split(',')
const sort = (a, b, i) => {
let sortKey = sortKeys[i]

View file

@ -15,7 +15,12 @@ DATALAYER_DATA = {
"features": [
{
"type": "Feature",
"properties": {"name": "one point in france", "foo": "point", "bar": "one"},
"properties": {
"name": "one point in france",
"foo": "point",
"bar": "one",
"label": "this is label one",
},
"geometry": {"type": "Point", "coordinates": [3.339844, 46.920255]},
},
{
@ -24,6 +29,7 @@ DATALAYER_DATA = {
"name": "one polygon in greenland",
"foo": "polygon",
"bar": "two",
"label": "this is label two",
},
"geometry": {
"type": "Polygon",
@ -44,6 +50,7 @@ DATALAYER_DATA = {
"name": "one line in new zeland",
"foo": "line",
"bar": "three",
"label": "this is label three",
},
"geometry": {
"type": "LineString",
@ -476,3 +483,11 @@ def test_main_toolbox_toggle_all_layers(live_server, map, page):
# Should hidden again all layers
expect(page.locator(".datalayer.off")).to_have_count(3)
expect(markers).to_have_count(0)
def test_honour_the_label_fields_settings(live_server, map, page, bootstrap, settings):
settings.UMAP_LABEL_KEYS = ["label", "name"]
page.goto(f"{live_server.url}{map.get_absolute_url()}")
expect(page.locator(".panel").get_by_text("this is label one")).to_be_visible()
expect(page.locator(".panel").get_by_text("this is label two")).to_be_visible()
expect(page.locator(".panel").get_by_text("this is label three")).to_be_visible()

View file

@ -609,6 +609,7 @@ class MapDetailMixin(SessionMixin):
"websocketEnabled": settings.WEBSOCKET_ENABLED,
"websocketURI": settings.WEBSOCKET_FRONT_URI,
"importers": settings.UMAP_IMPORTERS,
"defaultLabelKeys": settings.UMAP_LABEL_KEYS,
}
created = bool(getattr(self, "object", None))
if (created and self.object.owner) or (not created and not user.is_anonymous):