Add multiple network maps, graph UX improvements, and full backup import.
Support per-map contact membership with scoped graph views, relation editing on edges, layout caching, and automatic detection of full JSON backups so contacts and relations import together. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<div v-if="open" class="modal-overlay" @click.self="$emit('close')">
|
||||
<div class="modal">
|
||||
<div class="modal-header">
|
||||
<h3>Добавить на карту</h3>
|
||||
<button class="btn btn-secondary btn-sm" type="button" @click="$emit('close')">✕</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Контакт</label>
|
||||
<SearchableSelect
|
||||
v-model="selectedContactId"
|
||||
:options="contactOptions"
|
||||
placeholder="Выберите контакт..."
|
||||
/>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" @click="$emit('close')">Отмена</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
:disabled="!selectedContactId"
|
||||
@click="onAdd"
|
||||
>
|
||||
Добавить
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import SearchableSelect from './SearchableSelect.vue'
|
||||
|
||||
const props = defineProps({
|
||||
open: { type: Boolean, default: false },
|
||||
contacts: { type: Array, default: () => [] },
|
||||
memberContactIds: { type: Array, default: () => [] },
|
||||
})
|
||||
const emit = defineEmits(['close', 'add'])
|
||||
|
||||
const selectedContactId = ref('')
|
||||
|
||||
const memberSet = computed(() => new Set(props.memberContactIds.map(String)))
|
||||
|
||||
const contactOptions = computed(() =>
|
||||
props.contacts
|
||||
.filter((c) => !memberSet.value.has(String(c.id)))
|
||||
.map((c) => ({ value: String(c.id), label: c.name }))
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.open,
|
||||
(isOpen) => {
|
||||
if (isOpen) selectedContactId.value = ''
|
||||
}
|
||||
)
|
||||
|
||||
function onAdd() {
|
||||
if (!selectedContactId.value) return
|
||||
emit('add', selectedContactId.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user