Files
social-graph/frontend/src/components/NetworkMapTopPanel.vue
T
gitrusprusandCursor 986d36ff51 Improve graph/map UX and move contact editing to dedicated pages.
Add viewport controls, collapsible panels with persisted state, filters modal, and refined context menus; preserve map layout on navigation and let contacts be edited with relations on /contacts/:id instead of list modals.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 15:15:45 +03:00

111 lines
2.4 KiB
Vue

<template>
<div class="network-map-top-panel" :class="{ collapsed }">
<button
class="panel-toggle-btn"
@click="$emit('toggle-collapse')"
:title="collapsed ? 'Развернуть панель' : 'Свернуть панель'"
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polyline v-if="!collapsed" points="18 15 12 9 6 15" />
<polyline v-else points="6 9 12 15 18 9" />
</svg>
</button>
<div class="network-map-header" v-show="!collapsed">
<div>
<h2>{{ title }}</h2>
<p v-if="subtitle" class="network-map-sub">{{ subtitle }}</p>
</div>
<div class="network-map-actions">
<slot name="toolbar" />
</div>
</div>
<div v-show="!collapsed && showLegend" class="network-map-legend">
<slot name="legend" />
</div>
</div>
</template>
<script setup>
defineProps({
collapsed: { type: Boolean, default: false },
title: { type: String, default: 'Карта сети' },
subtitle: {
type: String,
default: '',
},
showLegend: { type: Boolean, default: true },
})
defineEmits(['toggle-collapse'])
</script>
<style scoped>
.network-map-top-panel {
position: relative;
z-index: 5;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
padding-bottom: 10px;
}
.network-map-top-panel.collapsed {
min-height: 28px;
padding-bottom: 10px;
}
.panel-toggle-btn {
position: absolute;
bottom: 4px;
left: 50%;
z-index: 6;
width: 28px;
height: 20px;
margin-left: -14px;
border: 1px solid var(--border);
border-radius: 6px;
background: var(--surface-alt);
color: var(--text-muted);
display: grid;
place-items: center;
cursor: pointer;
}
.panel-toggle-btn:hover {
color: var(--text);
border-color: var(--accent);
}
.network-map-header {
flex-shrink: 0;
padding: 12px 28px 8px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
}
.network-map-header h2 {
font-size: 18px;
font-weight: 600;
margin: 0 0 6px;
}
.network-map-sub {
margin: 0;
font-size: 13px;
color: var(--text-muted);
max-width: 640px;
line-height: 1.45;
}
.network-map-toolbar {
display: none;
}
.network-map-actions {
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
justify-content: flex-end;
padding-left: 16px;
padding-right: 16px;
}
.network-map-legend {
padding: 0 28px 14px;
}
</style>