From cb685446a501c4e744e545ff13ea65b88a6993b7 Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev <572431+veikab@users.noreply.github.com> Date: Tue, 24 Feb 2026 21:45:01 +0700 Subject: [PATCH] fix: show loading spinner when switching between contact threads Clear old timeline items immediately on thread switch and display a centered loader until the new conversation loads, instead of showing stale messages. Co-Authored-By: Claude Opus 4.6 --- .../components/workspace/CrmWorkspaceApp.vue | 8 ++++++++ frontend/app/composables/useTimeline.ts | 19 +++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/frontend/app/components/workspace/CrmWorkspaceApp.vue b/frontend/app/components/workspace/CrmWorkspaceApp.vue index 13b037b..2835334 100644 --- a/frontend/app/components/workspace/CrmWorkspaceApp.vue +++ b/frontend/app/components/workspace/CrmWorkspaceApp.vue @@ -259,6 +259,7 @@ const { // --------------------------------------------------------------------------- const { clientTimelineItems, + timelineLoading, timelineContactId, timelineLimit, loadClientTimeline, @@ -1624,6 +1625,12 @@ onBeforeUnmount(() => {
+ +
+ +
+ +
}) { ); const clientTimelineItems = ref([]); + const timelineLoading = ref(false); watch(() => timelineResult.value?.getClientTimeline, (v) => { - if (v) clientTimelineItems.value = v as ClientTimelineItem[]; + if (v) { + clientTimelineItems.value = v as ClientTimelineItem[]; + timelineLoading.value = false; + } }, { immediate: true }); async function loadClientTimeline(contactId: string, limit = 500) { @@ -40,18 +44,28 @@ export function useTimeline(opts: { apolloAuthReady: ComputedRef }) { if (!normalizedContactId) { clientTimelineItems.value = []; timelineContactId.value = ""; + timelineLoading.value = false; return; } + // Clear old data immediately and show loader + clientTimelineItems.value = []; + timelineLoading.value = true; + timelineContactId.value = normalizedContactId; timelineLimit.value = limit; - await refetchTimeline(); + try { + await refetchTimeline(); + } finally { + timelineLoading.value = false; + } } async function refreshSelectedClientTimeline(selectedCommThreadId: string) { const contactId = String(selectedCommThreadId ?? "").trim(); if (!contactId) { clientTimelineItems.value = []; + timelineLoading.value = false; return; } await loadClientTimeline(contactId); @@ -59,6 +73,7 @@ export function useTimeline(opts: { apolloAuthReady: ComputedRef }) { return { clientTimelineItems, + timelineLoading, timelineContactId, timelineLimit, loadClientTimeline,