Add modal for node details with map view and country flag rendering, enhance table interactions with row-click handling

This commit is contained in:
Jan 2026-01-04 19:30:34 +01:00
parent 1ceca3f2f1
commit d606e3e33a

View file

@ -1,8 +1,26 @@
<template> <template>
<div class="nodes-container"> <div class="nodes-container">
<modal :state="showModal">
<div class="node-modal-container">
<div class="node-header">
<h3 class="sub-header"> {{ node.name }}
</h3>
<icon-button icon="x" @click="showModal = false"></icon-button>
</div>
<div class="node-body">
<div class="node-address"><flag :iso="node.country.iso_code" />{{ node.address }}</div>
<div class="supplier-map" v-if="node.location">
<open-street-map-embed :coordinates="node.location" :zoom="5" width="100%" height="300px"
custom-filter="grayscale(0.8) sepia(0.5) hue-rotate(180deg) saturate(0.5) brightness(1.0)"></open-street-map-embed>
</div>
</div>
</div>
</modal>
<table-view ref="tableViewRef" :data-source="fetch" :columns="nodeColumns" :page="pagination.page" <table-view ref="tableViewRef" :data-source="fetch" :columns="nodeColumns" :page="pagination.page"
:page-size="pageSize" :page-count="pagination.pageCount" :page-size="pageSize" :page-count="pagination.pageCount"
:total-count="pagination.totalCount"></table-view> :total-count="pagination.totalCount" @row-click="showDetails" :mouse-over="true"></table-view>
</div> </div>
@ -12,6 +30,12 @@
import TableView from "@/components/UI/TableView.vue"; import TableView from "@/components/UI/TableView.vue";
import {mapStores} from "pinia"; import {mapStores} from "pinia";
import {useNodeStore} from "@/store/node.js"; import {useNodeStore} from "@/store/node.js";
import Modal from "@/components/UI/Modal.vue";
import ErrorModal from "@/components/layout/error/ErrorModal.vue";
import TabContainer from "@/components/UI/TabContainer.vue";
import IconButton from "@/components/UI/IconButton.vue";
import OpenStreetMapEmbed from "@/components/UI/OpenStreetMapEmbed.vue";
import Flag from "@/components/UI/Flag.vue";
export default { export default {
name: "Nodes", name: "Nodes",
@ -28,7 +52,7 @@ export default {
} }
} }
}, },
components: {TableView}, components: {Flag, OpenStreetMapEmbed, IconButton, TabContainer, ErrorModal, Modal, TableView},
computed: { computed: {
...mapStores(useNodeStore), ...mapStores(useNodeStore),
}, },
@ -40,10 +64,16 @@ export default {
await this.nodeStore.setQuery(query); await this.nodeStore.setQuery(query);
this.pagination = this.nodeStore.pagination; this.pagination = this.nodeStore.pagination;
return this.nodeStore.nodes; return this.nodeStore.nodes;
},
showDetails(node) {
this.node = node;
this.showModal = true;
} }
}, },
data() { data() {
return { return {
showModal: false,
node: null,
nodeColumns: [ nodeColumns: [
{ {
key: 'external_mapping_id', key: 'external_mapping_id',
@ -95,4 +125,39 @@ export default {
padding: 2.4rem; padding: 2.4rem;
} }
.node-modal-container {
height: 40rem;
width: 60rem;
display: flex;
flex-direction: column;
overflow: hidden; /* Verhindert Overflow */
}
.node-header {
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0; /* Header soll nicht schrumpfen */
padding-bottom: 1.6rem; /* Optional: etwas Abstand */
}
.node-body {
flex: 1; /* Nimmt den restlichen Platz ein */
min-height: 0; /* Wichtig für Flexbox-Scrolling */
overflow: hidden; /* Container selbst soll nicht scrollen */
display: flex;
flex-direction: column;
gap: 1.6rem;
}
.node-address {
display: flex;
gap: 0.8rem;
color: #6b7280;
font-size: 1.4rem;
line-height: 1.4;
}
</style> </style>