feat: highlight source element when navigating from tables to edit page

Clicking the pencil icon in revenus/depenses tables now passes query
params to identify the source row. The edit page auto-expands the
matching section, scrolls to the element, and briefly highlights it
with a blue ring that fades after 2 seconds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 06:16:29 +01:00
parent 04db85c688
commit 5c9a8c9b5e
7 changed files with 145 additions and 13 deletions

View File

@@ -110,11 +110,12 @@
@toggle="toggleSection('locataires')"
>
<div class="space-y-2">
<LocataireCard
v-for="(loc, idx) in data.data?.situation_locataires"
<LocataireCard
v-for="(loc, idx) in data.data?.situation_locataires"
:key="idx"
:locataire="loc"
:index="idx"
:highlighted="highlightedLocataireIndex === idx"
@update:locataire="updateLocataire(idx, $event)"
@remove="removeLocataire(idx)"
/>
@@ -140,11 +141,12 @@
@toggle="toggleSection('operations')"
>
<div class="space-y-2">
<OperationCard
v-for="(group, idx) in operationsGroupedByCategory"
<OperationCard
v-for="(group, idx) in operationsGroupedByCategory"
:key="idx"
:categorie="group.categorie"
:operations="group.operations"
:highlightIndex="group.categorie === highlightOperationCategorie ? highlightOperationIndex : -1"
@update:operations="updateOperationsGroup(group.categorie, $event)"
/>
@@ -166,7 +168,7 @@
</template>
<script setup>
import { ref, reactive, computed } from 'vue'
import { ref, reactive, computed, watch } from 'vue'
import DataSection from './DataSection.vue'
import DataCard from './DataCard.vue'
import DataRow from './DataRow.vue'
@@ -181,6 +183,10 @@ const props = defineProps({
isLoading: {
type: Boolean,
default: false
},
highlight: {
type: Object,
default: null
}
})
@@ -214,6 +220,55 @@ const expandedSections = reactive({
operations: false
})
// Highlight state
const highlightedLocataireIndex = ref(-1)
const highlightOperationCategorie = ref(null)
const highlightOperationIndex = ref(-1)
watch(
() => [props.data, props.highlight],
([data, highlight]) => {
if (!data || !highlight) return
if (highlight.type === 'locataire') {
const locataires = data.data?.situation_locataires
if (!locataires) return
const idx = locataires.findIndex(
loc => loc.lot?.numero === highlight.lot_numero && loc.locataire?.nom === highlight.locataire_nom
)
if (idx >= 0) {
expandedSections.locataires = true
highlightedLocataireIndex.value = idx
}
}
if (highlight.type === 'operation') {
const operations = data.data?.recapitulatif_operations
if (!operations) return
// Find the matching operation and determine its category + index within that category group
let targetCategorie = null
let indexInGroup = -1
const categoryCounters = {}
for (const op of operations) {
const cat = op.categorie || 'AUTRES'
if (!(cat in categoryCounters)) categoryCounters[cat] = 0
if (op.fournisseur === highlight.fournisseur && op.description === highlight.description) {
targetCategorie = cat
indexInGroup = categoryCounters[cat]
break
}
categoryCounters[cat]++
}
if (targetCategorie !== null) {
expandedSections.operations = true
highlightOperationCategorie.value = targetCategorie
highlightOperationIndex.value = indexInGroup
}
}
},
{ immediate: true }
)
function toggleSection(section) {
expandedSections[section] = !expandedSections[section]
}