import { useState, useEffect } from "react"; import { Merge, CircleX, AlertTriangle, ArrowDown } from "lucide-react"; import { useDataProvider, useRecordContext, useGetList, useGetManyReference, required, Form, useNotify, useRedirect, useTranslate, } from "ra-core"; import type { Identifier } from "ra-core"; import { useMutation } from "@tanstack/react-query"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, } from "@/components/ds/ui/dialog"; import { Button } from "@/components/ds/ui/button"; import { ReferenceInput } from "@/components/ds/admin/reference-input"; import { AutocompleteInput } from "@/components/ds/admin/autocomplete-input"; import { Alert, AlertDescription, AlertTitle } from "@/components/ds/ui/alert"; import type { Company } from "../types"; export const CompanyMergeButton = () => { const [mergeDialogOpen, setMergeDialogOpen] = useState(false); const translate = useTranslate(); return ( <> setMergeDialogOpen(true)} > {translate("crm.company.action.merge_with_another")} setMergeDialogOpen(false)} /> > ); }; interface CompanyMergeDialogProps { open: boolean; onClose: () => void; } const CompanyMergeDialog = ({ open, onClose }: CompanyMergeDialogProps) => { const loserCompany = useRecordContext(); const notify = useNotify(); const redirect = useRedirect(); const dataProvider = useDataProvider(); const translate = useTranslate(); const [winnerId, setWinnerId] = useState(null); const [suggestedWinnerId, setSuggestedWinnerId] = useState( null, ); const [isMerging, setIsMerging] = useState(false); const { mutateAsync } = useMutation({ mutationKey: [ "companies", "merge", { loserId: loserCompany?.id, winnerId }, ], mutationFn: async () => { return dataProvider.mergeCompanies(loserCompany?.id, winnerId); }, }); // Find potential companies with matching name const { data: matchingCompanies } = useGetList( "companies", { filter: { name: loserCompany?.name, "id@neq": `${loserCompany?.id}`, // Exclude current company }, pagination: { page: 1, perPage: 10 }, }, { enabled: open && !!loserCompany }, ); // Get counts of items to be merged const canFetchCounts = open && !!loserCompany && !!winnerId; const { total: contactsCount } = useGetManyReference( "contacts", { target: "company_id", id: loserCompany?.id, pagination: { page: 1, perPage: 1 }, }, { enabled: canFetchCounts }, ); const { total: dealsCount } = useGetManyReference( "deals", { target: "company_id", id: loserCompany?.id, pagination: { page: 1, perPage: 1 }, }, { enabled: canFetchCounts }, ); useEffect(() => { if (matchingCompanies && matchingCompanies.length > 0) { const suggestedWinnerId = matchingCompanies[0].id; setSuggestedWinnerId(suggestedWinnerId); setWinnerId(suggestedWinnerId); } }, [matchingCompanies]); const handleMerge = async () => { if (!winnerId || !loserCompany) { notify(translate("crm.company.merge.select_company"), { type: "warning", }); return; } try { setIsMerging(true); await mutateAsync(); setIsMerging(false); notify(translate("crm.company.merge.success"), { type: "success" }); redirect(`/companies/${winnerId}/show`); onClose(); } catch (error) { setIsMerging(false); notify(translate("crm.company.merge.error"), { type: "error" }); console.error("Merge failed:", error); } }; if (!loserCompany) return null; return ( {translate("crm.company.merge.title")} {translate("crm.company.merge.description")} {translate("crm.company.merge.current_company")} {loserCompany.name} {translate("crm.company.merge.target_contact")} {winnerId && ( <> {translate("crm.company.merge.what_will_be_merged")} {contactsCount != null && contactsCount > 0 && ( •{" "} {translate("crm.company.merge.contacts_to_merge", { smart_count: contactsCount, })} )} {dealsCount != null && dealsCount > 0 && ( •{" "} {translate("crm.company.merge.deals_to_merge", { smart_count: dealsCount, })} )} {loserCompany.context_links?.length > 0 && ( •{" "} {translate("crm.company.merge.links_to_merge", { smart_count: loserCompany.context_links.length, })} )} {!contactsCount && !dealsCount && !loserCompany.context_links?.length && ( {translate("crm.company.merge.no_data")} )} {translate("crm.company.merge.warning_title")} {translate("crm.company.merge.warning_message")} > )} {translate("crm.activity.cancel")} {isMerging ? translate("crm.company.merge.merging") : translate("crm.company.merge.merge_companies")} ); };
{translate("crm.company.merge.current_company")}
{translate("crm.company.merge.target_contact")}
{translate("crm.company.merge.what_will_be_merged")}