Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,87 @@ Different components expect different props:
- `active`: Whether the layer is initially visible.
- `clickable`: Whether clicking the map interacts with this layer.
- `propertiesBox` (optional): Name of a properties box configuration (used for showing feature attributes).
- **`conditionSource`** (optional): Name of a selection key to use when conditionally enabling layers (see “Use case selection and `selectionKey`” below).
- **`SelectionList`**:
- **`label`**: Label shown above the list.
- **`options`**: Array of `{ "id": "value", "name": "Label" }` entries.
- **`selectionKey`** (optional): Name under which the selected value is stored in the app store (`app.selections[selectionKey]`). If omitted, the value is only passed via the `step-complete` payload.
- **`NumberInput`**:
- Typical props include `label`, `suffix`, `min`, `max`, `step`, `defaultValue`, and `defaultValueSource` (see below under WPS input sources).

### Use case selection and `selectionKey`

In more advanced workflows, you can introduce an explicit “use case” selection step and use its stored value to drive which layers are shown later.

Example:

```json
{
"id": "userCaseSelection",
"title": "Use Case",
"drawerTitle": "Select your use case",
"components": [
{
"component": "SelectionList",
"componentProps": {
"label": "Use cases",
"selectionKey": "userCaseSelection",
"options": [
{ "id": "administration", "name": "Administration" },
{ "id": "hydrobasin", "name": "Hydro basin" }
]
}
}
]
}
```

With this configuration:

- **`SelectionList`**:
- Stores the chosen option under `app.selections.userCaseSelection` using `selectionKey`.
- Emits `step-complete` with a payload `{ "value": "<selected id>" }`, which can be used by WPS inputs via `source: "payload:value"`.

You can then make a later step conditionally show layers depending on this value by combining `conditionSource` and per-layer `condition` values:

```json
{
"id": "regionSelection",
"title": "Region Selection",
"requiredSteps": ["userCaseSelection"],
"components": [
{
"component": "LayerList",
"componentProps": {
"conditionSource": "userCaseSelection",
"layers": [
{
"id": "region:nuts_2021_level_3",
"name": "NUTS 3 Regions",
"active": true,
"clickable": true,
"propertiesBox": "region",
"condition": "administration"
},
{
"id": "topography:hybas_eu_lev12_v1c",
"name": "Hydro Basins",
"active": true,
"clickable": true,
"condition": "hydrobasin"
}
]
}
}
]
}
```

- **`conditionSource`** tells `LayerList` to read from `app.selections.userCaseSelection`.
- Each layer’s **`condition`** is compared to that value. Only layers matching the current selection are considered active/visible in the workflow.

This pattern lets you implement a “step 0” use case selection (e.g. NUTS vs Hydrobasins) entirely through configuration, without changing application code.

### Wiring menus together with `requiredSteps`

Menus can depend on the completion of earlier steps. For example:
Expand Down
30 changes: 28 additions & 2 deletions src/components/LayerList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Data Layers
</v-list-item>

<template v-for="layer in layers" :key="layer.id">
<template v-for="layer in filteredLayers" :key="layer.id">
<v-list-item>
<template #prepend>
<v-switch
Expand Down Expand Up @@ -32,20 +32,46 @@
</template>

<script setup>
import { onMounted } from 'vue'
import { computed, onMounted, watch } from 'vue'
import { useAppStore } from '@/stores/app'
import { useMapStore } from '@/stores/map'
import ActiveFeatureProperties from '@/components/ActiveFeatureProperties.vue'

const props = defineProps({
layers: { type: Array, required: true },
conditionSource: { type: String, default: null },
})

const appStore = useAppStore()
const mapStore = useMapStore()

const filteredLayers = computed(() => {
if (!props.conditionSource) {
return props.layers
}
const selected = appStore.selections[props.conditionSource]
return props.layers.filter(
layer => !layer.condition || layer.condition === selected,
)
})

function syncVisibilityToFilter () {
if (!props.conditionSource) return
const ids = new Set(filteredLayers.value.map(l => l.id))
for (const layer of props.layers) {
if (!ids.has(layer.id)) {
mapStore.setLayerVisibility(layer.id, false)
}
}
}

onMounted(() => {
mapStore.initializeLayerVisibility(props.layers)
mapStore.initializeLayerClickable(props.layers)
syncVisibilityToFilter()
})

watch(filteredLayers, syncVisibilityToFilter)
</script>

<style scoped>
Expand Down
16 changes: 14 additions & 2 deletions src/components/SelectionList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,29 @@
</template>

<script setup>
import { ref, watch } from 'vue'
import { ref, watch, onMounted } from 'vue'
import { useAppStore } from '@/stores/app'

defineProps({
const props = defineProps({
label: { type: String, required: true },
options: { type: Array, required: true },
selectionKey: { type: String, default: null },
})

const emit = defineEmits(['step-complete'])
const appStore = useAppStore()
const selected = ref(null)

onMounted(() => {
if (props.selectionKey && appStore.selections[props.selectionKey] != null) {
selected.value = appStore.selections[props.selectionKey]
}
})

watch(selected, (value) => {
if (props.selectionKey) {
appStore.setSelection(props.selectionKey, value)
}
if (value != null) {
emit('step-complete', { value })
}
Expand Down
74 changes: 59 additions & 15 deletions src/config/navigation.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
{
"logo": "/desirmed_logo.png",
"menus": [
{
"id": "userCaseSelection",
"title": "Use Case",
"drawerTitle": "Select your use case",
"components": [
{
"component": "SelectionList",
"componentProps": {
"label": "Use cases",
"selectionKey": "userCaseSelection",
"options": [
{
"id": "administration",
"name": "Administration"
},
{
"id": "hydrobasin",
"name": "Hydro basin"
}
]
}
}
]
},
{
"id": "regionSelection",
"title": "Region Selection",
"drawerTitle": "Select a base map",
"icon": "mdi-map-marker-radius",
"requiredSteps": [
"userCaseSelection"
],
"components": [
{
"component": "LayerList",
"componentProps": {
"conditionSource": "userCaseSelection",
"layers": [
{
"id": "landuse:U2018_CLC2018_V2020_20u1_cog",
Expand All @@ -22,20 +50,20 @@
"name": "NUTS 3 Regions",
"active": true,
"clickable": true,
"propertiesBox": "region"
"propertiesBox": "region",
"condition": "administration"
},
{
"id": "topography:hybas_eu_lev12_v1c",
"name": "Hydro Basins",
"active": true,
"clickable": true,
"condition": "hydrobasin"
}
]
}
}
],
"wps": {
"identifier": "lare_region",
"trigger": "mapClick",
"inputs": [
{ "id": "nutsname", "type": "LiteralData", "source": "store:map.activeRegion.properties.nuts_name" }
],
"storeResultAs": "regionSelection"
}
]
},
{
"id": "hazard",
Expand All @@ -49,8 +77,16 @@
"identifier": "lare_hazard",
"trigger": "stepComplete",
"inputs": [
{ "id": "nutsname", "type": "LiteralData", "source": "store:map.activeRegion.properties.nuts_name" },
{ "id": "hazard", "type": "LiteralData", "source": "payload:value" }
{
"id": "nutsname",
"type": "LiteralData",
"source": "store:map.activeRegion.properties.nuts_name"
},
{
"id": "hazard",
"type": "LiteralData",
"source": "payload:value"
}
],
"storeResultAs": "hazard"
},
Expand Down Expand Up @@ -97,8 +133,16 @@
"identifier": "lare_uom",
"trigger": "stepComplete",
"inputs": [
{ "id": "nutsname", "type": "LiteralData", "source": "store:map.activeRegion.properties.nuts_name" },
{ "id": "uomsize", "type": "LiteralData", "source": "payload:value" }
{
"id": "nutsname",
"type": "LiteralData",
"source": "store:map.activeRegion.properties.nuts_name"
},
{
"id": "uomsize",
"type": "LiteralData",
"source": "payload:value"
}
],
"storeResultAs": "uom"
},
Expand Down Expand Up @@ -167,4 +211,4 @@
]
}
]
}
}
Loading
Loading