Files
clientsflow/frontend/app/composables/useTimeline.ts
Ruslan Bakiev a4d8d81de9 refactor: decompose CrmWorkspaceApp.vue into 15 composables
Split the 6000+ line monolithic component into modular composables:
- crm-types.ts: shared types and utility functions
- useAuth, useContacts, useContactInboxes, useCalendar, useDeals,
  useDocuments, useFeed, useTimeline, usePilotChat, useCallAudio,
  usePins, useChangeReview, useCrmRealtime, useWorkspaceRouting
CrmWorkspaceApp.vue is now a thin orchestrator (~2500 lines) that
wires composables together with glue code, keeping template and
styles intact.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:05:01 +07:00

53 lines
1.7 KiB
TypeScript

import { ref, computed, watch, type ComputedRef } from "vue";
import { useQuery } from "@vue/apollo-composable";
import { GetClientTimelineQueryDocument } from "~~/graphql/generated";
import type { ClientTimelineItem } from "~/composables/crm-types";
export function useTimeline(opts: { apolloAuthReady: ComputedRef<boolean> }) {
const timelineContactId = ref("");
const timelineLimit = ref(500);
const { result: timelineResult, refetch: refetchTimeline } = useQuery(
GetClientTimelineQueryDocument,
() => ({ contactId: timelineContactId.value, limit: timelineLimit.value }),
{ enabled: computed(() => !!timelineContactId.value && opts.apolloAuthReady.value) },
);
const clientTimelineItems = ref<ClientTimelineItem[]>([]);
watch(() => timelineResult.value?.getClientTimeline, (v) => {
if (v) clientTimelineItems.value = v as ClientTimelineItem[];
}, { immediate: true });
async function loadClientTimeline(contactId: string, limit = 500) {
const normalizedContactId = String(contactId ?? "").trim();
if (!normalizedContactId) {
clientTimelineItems.value = [];
timelineContactId.value = "";
return;
}
timelineContactId.value = normalizedContactId;
timelineLimit.value = limit;
await refetchTimeline();
}
async function refreshSelectedClientTimeline(selectedCommThreadId: string) {
const contactId = String(selectedCommThreadId ?? "").trim();
if (!contactId) {
clientTimelineItems.value = [];
return;
}
await loadClientTimeline(contactId);
}
return {
clientTimelineItems,
timelineContactId,
timelineLimit,
loadClientTimeline,
refreshSelectedClientTimeline,
refetchTimeline,
};
}