File size: 2,482 Bytes
b9cd14b c85593f b9cd14b c85593f b9cd14b c85593f b9cd14b c85593f b9cd14b c85593f b9cd14b c85593f b9cd14b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | /**
* Merge one generated sequence row (email or LinkedIn) into grouped contacts for previews.
* When stepOrder is present (campaign wizard), dedupe by stepOrder + channel so merged timelines stay stable.
* Always returns new references (immutable) so React re-renders when LinkedIn rows stream in after emails.
*/
export function mergeSequenceIntoContacts(prev, sequence) {
const ch = sequence.channel || 'email';
const matchIdx = prev.findIndex(
(c) =>
c.firstName === sequence.firstName &&
c.lastName === sequence.lastName &&
c.email === sequence.email
);
const stepOrder =
sequence.stepOrder != null && sequence.stepOrder !== undefined ? sequence.stepOrder : null;
const step = {
emailNumber: sequence.emailNumber || 1,
subject: sequence.subject,
emailContent: sequence.emailContent,
channel: ch,
stepOrder,
};
const dedupeKey =
stepOrder != null ? `ord-${stepOrder}-${ch}` : `${ch}-${step.emailNumber}`;
if (matchIdx === -1) {
const base = {
id: sequence.id,
firstName: sequence.firstName,
lastName: sequence.lastName,
email: sequence.email,
company: sequence.company,
title: sequence.title,
product: sequence.product,
emails: [],
linkedin: [],
};
if (ch === 'linkedin') {
base.linkedin = [step];
} else {
base.emails = [step];
}
return [...prev, base];
}
const existing = prev[matchIdx];
const emails = [...(existing.emails || [])];
const linkedin = [...(existing.linkedin || [])];
if (ch === 'linkedin') {
if (
!linkedin.some((e) => {
const k =
e.stepOrder != null ? `ord-${e.stepOrder}-${ch}` : `${ch}-${e.emailNumber}`;
return k === dedupeKey;
})
) {
linkedin.push(step);
}
} else {
if (
!emails.some((e) => {
const k =
e.stepOrder != null ? `ord-${e.stepOrder}-${ch}` : `${ch}-${e.emailNumber}`;
return k === dedupeKey;
})
) {
emails.push(step);
}
}
const updated = {
...existing,
emails,
linkedin,
};
return prev.map((c, i) => (i === matchIdx ? updated : c));
}
|