Now add the delete JS functions at the end of app.js:


Bash

Count lines in app.js


3967 /var/www/mssql.danmarcrm.com/dev1/extension2v1/public/assets/app.js


  3960→        if (!aiChat.isDragging) return;
  3961→        panel.style.right = 'auto'; panel.style.bottom = 'auto';
  3962→        panel.style.left = Math.max(0, Math.min(e.clientX - aiChat.dragOffsetX, window.innerWidth - panel.offsetWidth)) + 'px';
  3963→        panel.style.top = Math.max(0, Math.min(e.clientY - aiChat.dragOffsetY, window.innerHeight - panel.offsetHeight)) + 'px';
  3964→    });
  3965→    document.addEventListener('mouseup', function() { aiChat.isDragging = false; });
  3966→});
  3967→
  3968→

        if (!aiChat.isDragging) return;
        panel.style.right = 'auto'; panel.style.bottom = 'auto';
        panel.style.left = Math.max(0, Math.min(e.clientX - aiChat.dragOffsetX, window.innerWidth - panel.offsetWidth)) + 'px';
        panel.style.top = Math.max(0, Math.min(e.clientY - aiChat.dragOffsetY, window.innerHeight - panel.offsetHeight)) + 'px';
    });
    document.addEventListener('mouseup', function() { aiChat.isDragging = false; });
});


Edit

    document.addEventListener('mouseup', function() { aiChat.isDragging = false; });
});

    document.addEventListener('mouseup', function() { aiChat.isDragging = false; });
});

// ============================================
// DELETE FUNCTIONS
// ============================================
async function deleteContact(contactId, contactName) {
    if (!confirm('Delete contact "' + contactName + '" and ALL associated data (emails, analysis, profiles, memories)?\n\nThis cannot be undone.')) return;

    try {
        const response = await fetch('api.php?action=delete_contact', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({contact_id: contactId})
        });
        const data = await response.json();
        if (data.success) {
            alert('Contact deleted. Removed: ' + (data.deleted.emails || 0) + ' emails, ' + (data.deleted.thread_analysis || 0) + ' analyses.');
            loadContacts(state.contacts.page);
            loadEmails(state.emails.page);
        } else {
            alert('Error: ' + (data.error || 'Delete failed'));
        }
    } catch(e) {
        alert('Error deleting contact: ' + e.message);
    }
}

async function deleteThread(threadId, subject) {
    if (!confirm('Delete thread "' + subject + '" and all associated emails/analysis?\n\nThis cannot be undone.')) return;

    try {
        const response = await fetch('api.php?action=delete_thread', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({thread_id: threadId})
        });
        const data = await response.json();
        if (data.success) {
            alert('Thread deleted. Removed: ' + (data.deleted.emails || 0) + ' emails.');
            loadEmails(state.emails.page);
        } else {
            alert('Error: ' + (data.error || 'Delete failed'));
        }
    } catch(e) {
        alert('Error deleting thread: ' + e.message);
    }
}

async function deleteThreadsByEmail(email, domain) {
    var target = email || ('@' + domain);
    if (!confirm('Delete ALL threads involving ' + target + '?\n\nThis removes all emails, analysis, and AI responses for those threads. Cannot be undone.')) return;

    try {
        var body = {};
        if (email) body.email = email;
        if (domain) body.domain = domain;
        const response = await fetch('api.php?action=delete_threads_by_email', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(body)
        });
        const data = await response.json();
        if (data.success) {
            alert('Deleted ' + data.deleted.thread_count + ' threads, ' + data.deleted.emails + ' emails.');
            loadContacts(state.contacts.page);
            loadEmails(state.emails.page);
        } else {
            alert('Error: ' + (data.error || 'Delete failed'));
        }
    } catch(e) {
        alert('Error: ' + e.message);
    }
}