From 3833788aa8a4132036aadf2aa4acb6a7f69907a3 Mon Sep 17 00:00:00 2001 From: Mahdi Date: Sun, 27 Sep 2026 20:18:44 +0330 Subject: [PATCH] Fix Leads row menu overflow and add edit/delete actions. Use a teleported dropdown so the menu stays above the table, with edit modal and archive delete. --- apps/web/src/views/LeadsView.vue | 138 +++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 34 deletions(-) diff --git a/apps/web/src/views/LeadsView.vue b/apps/web/src/views/LeadsView.vue index 601c188..5f9fb8c 100644 --- a/apps/web/src/views/LeadsView.vue +++ b/apps/web/src/views/LeadsView.vue @@ -11,6 +11,7 @@ import { useAuthStore } from '@/stores/auth'; import { canManageSettings } from '@/lib/roles'; import { UiButton, + UiDropdownMenu, UiEmptyState, UiModal, UiPageHeader, @@ -69,6 +70,7 @@ const importJob = ref(null); const createOpen = ref(false); const createBusy = ref(false); const createError = ref(''); +const editingLeadId = ref(null); const createForm = ref({ title: '', contactName: '', @@ -359,7 +361,12 @@ async function load() { } } +const createModalTitle = computed(() => + editingLeadId.value ? 'ویرایش لید' : 'ثبت لید جدید', +); + function openCreate() { + editingLeadId.value = null; createError.value = ''; createForm.value = { title: '', @@ -376,6 +383,42 @@ function openCreate() { createOpen.value = true; } +function openEdit(lead: LeadDto) { + rowMenuId.value = null; + editingLeadId.value = lead.id; + createError.value = ''; + createForm.value = { + title: lead.title, + contactName: lead.contactName ?? '', + mobile: lead.mobile, + city: lead.city ?? '', + region: lead.region ?? '', + source: lead.source ?? '', + stageId: lead.stageId, + assigneeId: lead.assigneeId ?? '', + }; + closePick(); + closeSource(); + createOpen.value = true; +} + +async function deleteLead(lead: LeadDto) { + rowMenuId.value = null; + if (!confirm(`لید «${lead.title}» حذف (بایگانی) شود؟`)) return; + busy.value = true; + error.value = ''; + try { + await api.post('/leads/archive', { leadIds: [lead.id] }); + okMsg.value = 'لید حذف شد.'; + selected.value = new Set([...selected.value].filter((id) => id !== lead.id)); + await load(); + } catch { + error.value = 'حذف لید ناموفق بود.'; + } finally { + busy.value = false; + } +} + function applyContactDraft(draft: PhoneContactDraft) { if (draft.mobile) { createForm.value.mobile = draft.mobile; @@ -490,26 +533,36 @@ async function submitCreate() { return; } createBusy.value = true; + const payload = { + title: createForm.value.title.trim(), + mobile: createForm.value.mobile.trim(), + contactName: createForm.value.contactName.trim() || null, + city: createForm.value.city.trim() || null, + region: createForm.value.region.trim() || null, + source: createForm.value.source.trim() || null, + stageId: createForm.value.stageId || undefined, + assigneeId: createForm.value.assigneeId || null, + }; try { - const { data: created } = await api.post('/leads', { - title: createForm.value.title.trim(), - mobile: createForm.value.mobile.trim(), - contactName: createForm.value.contactName.trim() || null, - city: createForm.value.city.trim() || null, - region: createForm.value.region.trim() || null, - source: createForm.value.source.trim() || null, - stageId: createForm.value.stageId || undefined, - assigneeId: createForm.value.assigneeId || null, - }); - createOpen.value = false; - okMsg.value = 'لید جدید ثبت شد.'; - await load(); - void router.push({ name: 'lead-detail', params: { id: created.id } }); + if (editingLeadId.value) { + await api.patch(`/leads/${editingLeadId.value}`, payload); + createOpen.value = false; + okMsg.value = 'لید به‌روز شد.'; + await load(); + } else { + const { data: created } = await api.post('/leads', payload); + createOpen.value = false; + okMsg.value = 'لید جدید ثبت شد.'; + await load(); + void router.push({ name: 'lead-detail', params: { id: created.id } }); + } } catch (e) { createError.value = axios.isAxiosError(e) && (e.response?.data as { message?: string })?.message ? String((e.response?.data as { message?: string }).message) - : 'ثبت لید ناموفق بود.'; + : editingLeadId.value + ? 'ویرایش لید ناموفق بود.' + : 'ثبت لید ناموفق بود.'; } finally { createBusy.value = false; } @@ -977,24 +1030,28 @@ onBeforeUnmount(stopImportPoll);
-
- + + تماس + - -
+