Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Release v1.30.0 - #minor #945

Merged
merged 11 commits into from
Jun 20, 2024
Merged
7 changes: 3 additions & 4 deletions src/modules/map/components/toolbox/TimeSlider.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ const yearCursorInput = ref(null)
const store = useStore()
const screenWidth = computed(() => store.state.ui.width)
const lang = computed(() => store.state.i18n.lang)
const layersWithTimestamps = computed(() =>
store.getters.visibleLayers.filter((layer) => layer.hasMultipleTimestamps)
)
const layersWithTimestamps = computed(() => store.getters.visibleLayersWithTimeConfig)
const activeLayers = computed(() => store.state.layers.activeLayers)
const previewYear = computed(() => store.state.layers.previewYear)

Expand Down Expand Up @@ -241,7 +239,6 @@ onMounted(() => {

onUnmounted(() => {
window.removeEventListener('keydown', handleKeyDownEvent)
setPreviewYearToLayers()

tippyTimeSliderInfo?.destroy()
})
Expand All @@ -251,6 +248,7 @@ function setPreviewYearToLayers() {
activeLayers.value.forEach((layer, index) => {
const year = previewYear.value
if (
layer.visible &&
layer.hasMultipleTimestamps &&
layer.timeConfig &&
layer.timeConfig.getTimeEntryForYear(year)
Expand All @@ -266,6 +264,7 @@ function setPreviewYearToLayers() {

function dispatchPreviewYearToStore() {
store.dispatch('setPreviewYear', { year: currentYear.value, ...dispatcher })
setPreviewYearToLayers()
}

const dispatchPreviewYearToStoreDebounced = debounce(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
CURRENT_YEAR_WMTS_TIMESTAMP,
YEAR_TO_DESCRIBE_ALL_OR_CURRENT_DATA,
} from '@/api/layers/LayerTimeConfigEntry.class'
import TextTruncate from '@/utils/components/TextTruncate.vue'

const dispatcher = { dispatcher: 'MenuActiveLayersListItemTimeSelector.vue' }

Expand Down Expand Up @@ -110,35 +111,23 @@ function hidePopover() {
popover?.hide()
}

// for CSS : isSelected refers to either the current year, or the preview year if the time slider is active and the layer is visible
function isSelected(timeEntry) {
return isTimeSliderActive.value && isLayerVisible.value
? previewYear.value === timeEntry?.year
: timeConfig.value.currentTimestamp === timeEntry?.timestamp
}
// for CSS : baseYear refer to the year to which the timestamp will return to when the time slider is unmounted.
function baseYear(timeEntry) {
return (
isTimeSliderActive.value &&
isLayerVisible.value &&
timeConfig.value.currentTimestamp === timeEntry?.timestamp &&
timeEntry?.year !== previewYear.value
)
return timeConfig.value.currentTimestamp === timeEntry?.timestamp
}
</script>

<template>
<button
v-if="hasMultipleTimestamps"
ref="timeSelectorButton"
class="btn btn-secondary me-2 btn-timestamp"
class="btn btn-secondary me-1 btn-timestamp btn-timestamp-selector"
:class="{
'btn-sm': compact,
'w-13': compact,
'btn-timestamp-selector-compact': compact,
}"
:data-cy="`time-selector-${layerId}-${layerIndex}`"
>
{{ humanReadableCurrentTimestamp }}
<TextTruncate>{{ humanReadableCurrentTimestamp }}</TextTruncate>
</button>
<div
v-if="hasMultipleTimestamps"
Expand All @@ -156,16 +145,15 @@ function baseYear(timeEntry) {
<button
v-for="timeEntry in timeConfig.timeEntries"
:key="timeEntry.timestamp"
class="btn mb-1 me-1 btn-timestamp"
class="btn mb-1 me-1 btn-timestamp-selection-popup"
:class="{
'btn-primary': isSelected(timeEntry),
'btn-outline-primary': baseYear(timeEntry),
'btn-light': !isSelected(timeEntry) && !baseYear(timeEntry),
'btn-light': !isSelected(timeEntry),
}"
:data-cy="`time-select-${timeEntry.timestamp}`"
@click="handleClickOnTimestamp(timeEntry.year)"
>
{{ renderHumanReadableTimestamp(timeEntry) }}
<TextTruncate>{{ renderHumanReadableTimestamp(timeEntry) }}</TextTruncate>
</button>
</div>
</div>
Expand All @@ -179,7 +167,22 @@ function baseYear(timeEntry) {
background: white;
grid-template-columns: 1fr 1fr 1fr;
}
.btn-timestamp {
white-space: nowrap;
.btn-timestamp-selection-popup {
max-width: 100px;
}
.btn-timestamp-selector {
font-size: small;
$btn-width: 68px; // 68px allow the word "Actual" in all languages without being truncated
// Here we need to use min/max-width otherwise the size is not always identical over all layers
min-width: $btn-width;
max-width: $btn-width;

&-compact {
$btn-width: 60px; // 60px allow the word "Actual" in all languages without being truncated
min-width: $btn-width;
max-width: $btn-width;
padding-top: 2px;
padding-bottom: 2px;
}
}
</style>
6 changes: 5 additions & 1 deletion src/modules/menu/components/common/MenuItemCheckBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { toRefs } from 'vue'
import { useI18n } from 'vue-i18n'

import TextTruncate from '@/utils/components/TextTruncate.vue'

const model = defineModel({ type: Boolean })
const emits = defineEmits(['click'])
const i18n = useI18n()
Expand Down Expand Up @@ -39,7 +41,9 @@ function onClick(ev) {
>
<FontAwesomeIcon :icon="`far fa-${model ? 'check-' : ''}square`" />
</button>
<label v-if="label" class="ms-2 menu-check-box-item-name">{{ i18n.t(label) }}</label>
<label v-if="label" class="ms-2 menu-check-box-item-name"
><TextTruncate>{{ i18n.t(label) }}</TextTruncate></label
>
</div>
</div>
</template>
Expand Down
3 changes: 0 additions & 3 deletions src/modules/menu/scss/menu-items.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,4 @@
.menu-name {
flex-grow: 1;
text-align: left;
text-overflow: ellipsis;
white-space: nowrap;
overflow-x: hidden;
}
8 changes: 4 additions & 4 deletions src/router/storeSync/LayerParamConfig.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ export function createLayerObject(parsedLayer, currentLayer) {
return new ExternalWMTSLayer({
id: parsedLayer.id,
name: parsedLayer.id,
opacity: parsedLayer.opacity,
visible: parsedLayer.visible ?? defaultOpacity,
opacity: parsedLayer.opacity ?? defaultOpacity,
visible: parsedLayer.visible,
baseUrl: parsedLayer.baseUrl,
currentYear: year,
})
Expand All @@ -88,8 +88,8 @@ export function createLayerObject(parsedLayer, currentLayer) {
return new ExternalWMSLayer({
id: parsedLayer.id,
name: parsedLayer.id,
opacity: parsedLayer.opacity,
visible: parsedLayer.visible ?? defaultOpacity,
opacity: parsedLayer.opacity ?? defaultOpacity,
visible: parsedLayer.visible,
baseUrl: parsedLayer.baseUrl,
currentYear: year,
})
Expand Down
26 changes: 21 additions & 5 deletions src/store/modules/layers.store.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,29 @@ const state = {

const getters = {
/**
* Filter all the active layers and gives only those who have the flag `visible` to `true`
* Filter all the active layers and gives only those who are visible on the map.
*
* This includes system layers and the preview layer. When the time slider is enabled, the time
* enabled layer with non matching preview year are filtered out.
*
* Layers are ordered from bottom to top (last layer is shown on top of all the others)
*
* @returns {AbstractLayer[]} All layers that are currently visible on the map
*/
visibleLayers: (state) => {
const visibleLayers = state.activeLayers.filter((layer) => layer.visible)
visibleLayers: (state, getters, rootState) => {
const visibleLayers = state.activeLayers.filter((layer) => {
// timeslider is not used on layer having only one timestamp as it doesn't make sense
// there.
if (
rootState.ui.isTimeSliderActive &&
layer.timeConfig &&
layer.hasMultipleTimestamps &&
layer.timeConfig.getTimeEntryForYear(state.previewYear) === null
) {
return false
}
return layer.visible
})
if (state.previewLayer !== null) {
visibleLayers.push(state.previewLayer)
}
Expand Down Expand Up @@ -177,12 +192,13 @@ const getters = {
},

/**
* Get visiblelayers with time config. (Preview and system layer are filtered)
* Get visiblelayers with time config. (Preview layers and system layers are filtered)
*
* @returns {GeoAdminLayer[]} List of layers with time config
*/
visibleLayersWithTimeConfig: (state) =>
// Here we cannot take the getter visibleLayers as it also contain the preview and system layers
// Here we cannot take the getter visibleLayers as it also contain the preview and system
// layers as well as the layer without matching previewYear are filtered out
state.activeLayers.filter((layer) => layer.visible && layer.hasMultipleTimestamps),

/**
Expand Down
4 changes: 4 additions & 0 deletions src/utils/featureStyleUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,10 @@ export function featureStyleFunction(feature, resolution) {
color: [...editableFeature.fillColor.rgb.slice(0, 3), 0.4],
}),
zIndex: 0,
stroke: new Stroke({
color: editableFeature.fillColor.fill,
width: 3,
}),
})
)
}
Expand Down
15 changes: 3 additions & 12 deletions tests/cypress/tests-e2e/timeSlider.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,6 @@ describe('Cypress tests covering the time slider, its functionalities and its UR
!classList.includes('btn-outline-primary')
)
}
function isPrimaryOutlineBtn(classList) {
return (
classList.includes('btn-outline-primary') &&
!classList.includes('btn-light') &&
!classList.includes('btn-primary')
)
}
function isLightBtn(classList) {
return (
classList.includes('btn-light') &&
Expand Down Expand Up @@ -215,9 +208,7 @@ describe('Cypress tests covering the time slider, its functionalities and its UR
if (timestamp === '20130101') {
return isPrimaryBtn(classList)
} else {
return timestamp === '20090101'
? isPrimaryOutlineBtn(classList)
: isLightBtn(classList)
return isLightBtn(classList)
}
})
})
Expand All @@ -232,7 +223,7 @@ describe('Cypress tests covering the time slider, its functionalities and its UR
// a light button

return timestamp === '20090101'
? isPrimaryOutlineBtn(classList)
? isPrimaryBtn(classList)
: isLightBtn(classList)
})
})
Expand Down Expand Up @@ -302,7 +293,7 @@ describe('Cypress tests covering the time slider, its functionalities and its UR
cy.get(`[data-cy="button-open-visible-layer-settings-${time_layer_std}-0"]`).click()
cy.get(`[data-cy="button-duplicate-layer-${time_layer_std}-0"]`).click()
cy.get(`[data-cy="button-toggle-visibility-layer-${time_layer_std}-0"]`).click()
cy.get(`[data-cy="time-selector-${time_layer_std}-0"]`).should('contain', 2019)
cy.get(`[data-cy="time-selector-${time_layer_std}-0"]`).should('contain', 2017)
cy.get(`[data-cy="time-selector-${time_layer_std}-1"]`).should('contain', 2017)

// ---------------------------------------------------------------------------------------------------
Expand Down
Loading