PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 3.2.24
MxChat – AI Chatbot & Content Generation for WordPress v3.2.24
3.2.25 3.2.24 3.2.23 3.2.22 3.2.21 3.2.20 3.2.19 3.2.18 3.2.17 3.2.16 3.2.15 3.2.14 3.2.12 3.2.13 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 All 156 releases
← All changes | js/mxchat_transcripts.js +35 -8 3.2.20 → 3.2.24 View file →
@@ -1638,8 +1638,26 @@
1638 1638 });
1639 1639 $wrap.html(html);
1640 1640 }
1641 1641
1642 + // A lead's key is its email address, or "session:<id>" when the capture
1643 + // had no address (c0cfaf). Email keys are lowercased exactly as before;
1644 + // session keys pass through untouched, because the server resolves them
1645 + // back to a real session id and case matters there. Both shapes travel on
1646 + // the same wire field the tab has always used, so the selection set, the
1647 + // delete call and the export call need no new parameter.
1648 + function leadKeyOf(r) {
1649 + const email = (r && r.email ? String(r.email) : '').trim();
1650 + if (email) return email.toLowerCase();
1651 + if (r && r.lead_key) return String(r.lead_key);
1652 + return 'session:' + (r && r.latest_session_id ? r.latest_session_id : '');
1653 + }
1654 +
1655 + function normalizeLeadKey(value) {
1656 + const key = (value === undefined || value === null) ? '' : String(value);
1657 + return key.indexOf('session:') === 0 ? key : key.toLowerCase();
1658 + }
1659 +
1642 1660 function renderLeadsTable(rows) {
1643 1661 const $tbody = $('#mxch-leads-tbody');
1644 1662 if (!rows || rows.length === 0) {
1645 1663 $tbody.html(`
@@ -1654,9 +1672,9 @@
1654 1672 }
1655 1673
1656 1674 let html = '';
1657 1675 rows.forEach(function(r) {
1658 - const emailKey = (r.email || '').toLowerCase();
1676 + const emailKey = leadKeyOf(r);
1659 1677 const isChecked = leadsState.selected.has(emailKey) ? ' checked' : '';
1660 1678 // Status: 'active' (has conversations), 'chat_deleted' (admin removed the chat), 'orphan' (no chat ever).
1661 1679 const status = r.status || (r.is_orphan ? 'orphan' : 'active');
1662 1680 const isOrphan = (status === 'orphan');
@@ -1663,12 +1681,21 @@
1663 1681 const isChatDeleted = (status === 'chat_deleted');
1664 1682 const nameLine = r.name
1665 1683 ? `<span class="mxch-leads-lead-name">${escapeHtmlLeads(r.name)}</span>`
1666 1684 : '';
1685 + // A lead captured with no email address (c0cfaf) still has a
1686 + // name; show that on the primary line rather than an empty cell,
1687 + // and say plainly that there is no address.
1688 + const primaryLine = r.email
1689 + ? `<span class="mxch-leads-lead-email" title="${escapeHtmlLeads(r.email)}">${escapeHtmlLeads(r.email)}</span>`
1690 + : `<span class="mxch-leads-lead-email">${escapeHtmlLeads(r.name || 'Unnamed lead')}</span>`;
1691 + const secondaryLine = r.email
1692 + ? nameLine
1693 + : '<span class="mxch-leads-muted">No email address</span>';
1667 1694 const leadCell = `
1668 1695 <div class="mxch-leads-lead-cell">
1669 - <span class="mxch-leads-lead-email" title="${escapeHtmlLeads(r.email)}">${escapeHtmlLeads(r.email)}</span>
1670 - ${nameLine}
1696 + ${primaryLine}
1697 + ${secondaryLine}
1671 1698 </div>`;
1672 1699 let countCell;
1673 1700 if (isOrphan) {
1674 1701 countCell = `<span class="mxch-leads-pill mxch-leads-pill-orphan">Orphan</span>`;
@@ -1697,15 +1724,15 @@
1697 1724 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
1698 1725 <span>View convo</span>
1699 1726 </button>`
1700 1727 : '';
1701 - const deleteBtn = `<button type="button" class="mxch-btn mxch-btn-ghost mxch-btn-sm mxch-btn-danger-ghost mxch-leads-delete-row" data-email="${escapeHtmlLeads(r.email)}" title="Delete lead">
1728 + const deleteBtn = `<button type="button" class="mxch-btn mxch-btn-ghost mxch-btn-sm mxch-btn-danger-ghost mxch-leads-delete-row" data-email="${escapeHtmlLeads(emailKey)}" title="Delete lead">
1702 1729 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
1703 1730 </button>`;
1704 1731
1705 1732 const rowStateClass = isOrphan ? ' is-orphan' : (isChatDeleted ? ' is-chat-deleted' : '');
1706 1733 html += `
1707 - <tr class="mxch-leads-row${rowStateClass}" data-email="${escapeHtmlLeads(r.email)}">
1734 + <tr class="mxch-leads-row${rowStateClass}" data-email="${escapeHtmlLeads(emailKey)}">
1708 1735 <td class="mxch-leads-col-check"><input type="checkbox" class="mxch-leads-rowcheck"${isChecked}></td>
1709 1736 <td class="mxch-leads-col-lead">${leadCell}</td>
1710 1737 <td class="mxch-leads-col-count">${countCell}</td>
1711 1738 <td class="mxch-leads-col-last">${lastCell}</td>
@@ -1832,9 +1859,9 @@
1832 1859 $('#mxch-leads-select-all').on('change', function() {
1833 1860 const on = $(this).is(':checked');
1834 1861 $('.mxch-leads-rowcheck').prop('checked', on);
1835 1862 $('.mxch-leads-row').each(function() {
1836 - const email = ($(this).data('email') || '').toString().toLowerCase();
1863 + const email = normalizeLeadKey($(this).data('email'));
1837 1864 if (on) {
1838 1865 leadsState.selected.add(email);
1839 1866 } else {
1840 1867 leadsState.selected.delete(email);
@@ -1844,9 +1871,9 @@
1844 1871 });
1845 1872
1846 1873 // Row checkbox
1847 1874 $leads().on('change', '.mxch-leads-rowcheck', function() {
1848 - const email = ($(this).closest('.mxch-leads-row').data('email') || '').toString().toLowerCase();
1875 + const email = normalizeLeadKey($(this).closest('.mxch-leads-row').data('email'));
1849 1876 if ($(this).is(':checked')) {
1850 1877 leadsState.selected.add(email);
1851 1878 } else {
1852 1879 leadsState.selected.delete(email);
@@ -1912,9 +1939,9 @@
1912 1939 success: function(response) {
1913 1940 $btn.prop('disabled', false).text('Delete permanently');
1914 1941 closeLeadsConfirm();
1915 1942 if (response && response.success) {
1916 - emails.forEach(function(e) { leadsState.selected.delete(e.toLowerCase()); });
1943 + emails.forEach(function(e) { leadsState.selected.delete(normalizeLeadKey(e)); });
1917 1944 loadLeads(leadsState.page);
1918 1945 } else {
1919 1946 alert((response && response.data && response.data.message) || 'Failed to delete leads.');
1920 1947 }