From ec9a7cf9c93736fd793e4aaf5f36194287396290 Mon Sep 17 00:00:00 2001 From: Mahdi Date: Wed, 11 Nov 2026 15:06:20 +0330 Subject: [PATCH] feat(deals): plan activities on the deal and create them from the board Show related activities on deal detail, prefill dealId on activity create, and add a side-panel quick create from pipeline cards. Co-authored-by: Cursor --- .../activities/RelatedActivitiesPanel.vue | 393 ++++++++++++++++++ apps/web/src/components/pipeline/DealCard.vue | 78 ++-- .../pipeline/DealQuickActivityPopover.vue | 376 +++++++++++++++++ apps/web/src/lib/pipeline-board.ts | 11 +- apps/web/src/views/ActivityFormView.vue | 10 + apps/web/src/views/DealFormView.vue | 9 + 6 files changed, 845 insertions(+), 32 deletions(-) create mode 100644 apps/web/src/components/activities/RelatedActivitiesPanel.vue create mode 100644 apps/web/src/components/pipeline/DealQuickActivityPopover.vue diff --git a/apps/web/src/components/activities/RelatedActivitiesPanel.vue b/apps/web/src/components/activities/RelatedActivitiesPanel.vue new file mode 100644 index 0000000..6f39329 --- /dev/null +++ b/apps/web/src/components/activities/RelatedActivitiesPanel.vue @@ -0,0 +1,393 @@ + + + diff --git a/apps/web/src/components/pipeline/DealCard.vue b/apps/web/src/components/pipeline/DealCard.vue index a4bd9d9..556f7c4 100644 --- a/apps/web/src/components/pipeline/DealCard.vue +++ b/apps/web/src/components/pipeline/DealCard.vue @@ -1,5 +1,5 @@ + + diff --git a/apps/web/src/lib/pipeline-board.ts b/apps/web/src/lib/pipeline-board.ts index 7162445..c7b1923 100644 --- a/apps/web/src/lib/pipeline-board.ts +++ b/apps/web/src/lib/pipeline-board.ts @@ -20,6 +20,8 @@ export type PipelineDeal = { assigneeNames?: string[]; ownerId?: string | null; assigneeIds?: string[]; + personId?: string | null; + companyId?: string | null; /** متن‌های قابل جستجو (مشتری، شرکت، یادداشت، مسئولان …) */ searchFields?: Array; /** اولویت فعالیت؛ فقط روی کارت فعالیت نشان داده می‌شود */ @@ -36,6 +38,8 @@ export type PipelineUiCopy = { hideAmount?: boolean; /** کارت فعالیت: پرچم کنار عنوان و پنجرهٔ خلاصه به‌جای ورود مستقیم به جزئیات */ quickView?: boolean; + /** گوشه کارت: ایجاد سریع فعالیت برای معامله */ + quickActivity?: boolean; }; export const DEAL_BOARD_COPY: PipelineUiCopy = { @@ -45,6 +49,7 @@ export const DEAL_BOARD_COPY: PipelineUiCopy = { addItemAria: 'افزودن معامله به این مرحله', itemMenuAria: 'گزینه‌های معامله', listColTitle: 'معامله', + quickActivity: true, }; export const PROJECT_BOARD_COPY: PipelineUiCopy = { @@ -185,8 +190,8 @@ export function mapBoardToStages( expectedCloseAt: string | null; createdAt: string; promotedFromPriorAt: string | null; - person: { fullName: string } | null; - company: { name: string } | null; + person: { id?: string; fullName: string } | null; + company: { id?: string; name: string } | null; owner?: { id: string; fullName: string } | null; assignees?: Array<{ id: string; fullName: string }>; }>; @@ -239,6 +244,8 @@ export function mapBoardToStages( assigneeNames, ownerId: deal.owner?.id ?? null, assigneeIds: (deal.assignees ?? []).map((a) => a.id), + personId: deal.person?.id ?? null, + companyId: deal.company?.id ?? null, searchFields: [ deal.notes, deal.company?.name, diff --git a/apps/web/src/views/ActivityFormView.vue b/apps/web/src/views/ActivityFormView.vue index 77c76dc..8add5e6 100644 --- a/apps/web/src/views/ActivityFormView.vue +++ b/apps/web/src/views/ActivityFormView.vue @@ -544,6 +544,16 @@ async function load() { personId.value = incomingPerson; } leadId.value = typeof route.query.leadId === 'string' ? route.query.leadId : ''; + const incomingDeal = + typeof route.query.dealId === 'string' ? route.query.dealId : ''; + if (incomingDeal) { + dealId.value = incomingDeal; + const linkedDeal = deals.value.find((d) => d.id === incomingDeal); + if (linkedDeal?.person?.id && !personId.value) { + await ensurePersonLoaded(linkedDeal.person.id); + personId.value = linkedDeal.person.id; + } + } const incomingDef = typeof route.query.typeDefId === 'string' ? activityTypes.byId.value.get(route.query.typeDefId) diff --git a/apps/web/src/views/DealFormView.vue b/apps/web/src/views/DealFormView.vue index fde84b4..ba7dd38 100644 --- a/apps/web/src/views/DealFormView.vue +++ b/apps/web/src/views/DealFormView.vue @@ -45,6 +45,7 @@ import { toFaDigits } from '@/lib/jalali'; import { currencySuffix, formatMoney } from '@/lib/money'; import CustomFieldsSection from '@/components/CustomFieldsSection.vue'; import EntityTimeline from '@/components/EntityTimeline.vue'; +import RelatedActivitiesPanel from '@/components/activities/RelatedActivitiesPanel.vue'; import RelatedTasksPanel from '@/components/routines/RelatedTasksPanel.vue'; import JalaliDateInput from '@/components/JalaliDateInput.vue'; import MoneyInput from '@/components/MoneyInput.vue'; @@ -1014,6 +1015,14 @@ onMounted(load); +