Implement multiple phone numbers per workflow feature
Database Changes: - Added twp_workflow_phones junction table for many-to-many relationship - Updated activator to create and manage new table - Maintained backward compatibility with existing phone_number field Workflow Management: - Added set_workflow_phone_numbers() and get_workflow_phone_numbers() methods - Updated get_workflow_by_phone_number() to check both old and new structures - Enhanced save/update handlers to support phone_numbers array - Added AJAX endpoint for retrieving workflow phone numbers User Interface: - Replaced single phone number select with dynamic multi-select interface - Added "Add Number" and "Remove" buttons for managing multiple numbers - Updated workflow listing to display all assigned phone numbers - Enhanced JavaScript for phone number management and validation The webhook routing already supports multiple numbers since get_workflow_by_phone_number() was updated to check both structures. This feature allows users to assign multiple Twilio phone numbers to trigger the same workflow. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -203,7 +203,9 @@ jQuery(document).ready(function($) {
|
||||
response.data.forEach(function(number) {
|
||||
options += '<option value="' + number.phone_number + '">' + number.phone_number + ' (' + number.friendly_name + ')</option>';
|
||||
});
|
||||
$('#workflow-phone').html(options);
|
||||
|
||||
// Update all workflow phone selects (legacy and new)
|
||||
$('#workflow-phone, .workflow-phone-select').html(options);
|
||||
|
||||
// Call the callback if provided
|
||||
if (typeof callback === 'function') {
|
||||
@@ -213,6 +215,20 @@ jQuery(document).ready(function($) {
|
||||
});
|
||||
}
|
||||
|
||||
function loadWorkflowPhoneNumbers(workflowId, callback) {
|
||||
$.post(twp_ajax.ajax_url, {
|
||||
action: 'twp_get_workflow_phone_numbers',
|
||||
workflow_id: workflowId,
|
||||
nonce: twp_ajax.nonce
|
||||
}, function(response) {
|
||||
if (response.success) {
|
||||
callback(response.data);
|
||||
} else {
|
||||
callback([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Step type button handlers
|
||||
$(document).on('click', '.step-btn', function() {
|
||||
var stepType = $(this).data('step-type');
|
||||
@@ -1088,10 +1104,19 @@ jQuery(document).ready(function($) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Collect phone numbers from all selects
|
||||
var phoneNumbers = [];
|
||||
$('#workflow-phone-numbers select[name="phone_numbers[]"]').each(function() {
|
||||
var phoneNumber = $(this).val();
|
||||
if (phoneNumber && phoneNumbers.indexOf(phoneNumber) === -1) {
|
||||
phoneNumbers.push(phoneNumber);
|
||||
}
|
||||
});
|
||||
|
||||
var payload = {
|
||||
action: currentWorkflowId ? 'twp_update_workflow' : 'twp_save_workflow',
|
||||
workflow_name: workflowData.workflow_name,
|
||||
phone_number: workflowData.phone_number,
|
||||
phone_numbers: phoneNumbers,
|
||||
workflow_data: JSON.stringify({
|
||||
steps: workflowSteps,
|
||||
conditions: [],
|
||||
@@ -1161,11 +1186,46 @@ jQuery(document).ready(function($) {
|
||||
workflowSteps = [];
|
||||
}
|
||||
|
||||
// Load phone numbers and select the saved one
|
||||
// Load phone numbers and set up the workflow
|
||||
loadPhoneNumbers(function() {
|
||||
$('#workflow-phone').val(phoneNumberToSelect);
|
||||
// Trigger change event in case there are any listeners
|
||||
$('#workflow-phone').trigger('change');
|
||||
// Load assigned phone numbers for this workflow
|
||||
loadWorkflowPhoneNumbers(workflowId, function(phoneNumbers) {
|
||||
if (phoneNumbers && phoneNumbers.length > 0) {
|
||||
// Clear existing phone number inputs
|
||||
$('#workflow-phone-numbers').empty();
|
||||
|
||||
// Add phone number rows
|
||||
phoneNumbers.forEach(function(phoneNumber, index) {
|
||||
if (index === 0) {
|
||||
// First row with Add button
|
||||
var firstRow = '<div class="phone-number-row">' +
|
||||
'<select name="phone_numbers[]" class="workflow-phone-select" required></select>' +
|
||||
'<button type="button" class="button add-phone-number" style="margin-left: 10px;">' +
|
||||
(phoneNumbers.length === 1 ? 'Add Number' : 'Add Another Number') + '</button>' +
|
||||
'</div>';
|
||||
$('#workflow-phone-numbers').append(firstRow);
|
||||
} else {
|
||||
// Additional rows with Remove button
|
||||
var additionalRow = '<div class="phone-number-row" style="margin-top: 10px;">' +
|
||||
'<select name="phone_numbers[]" class="workflow-phone-select"></select>' +
|
||||
'<button type="button" class="button remove-phone-number" style="margin-left: 10px; background: #d63638; color: white;">Remove</button>' +
|
||||
'</div>';
|
||||
$('#workflow-phone-numbers').append(additionalRow);
|
||||
}
|
||||
});
|
||||
|
||||
// Repopulate selects and set values
|
||||
loadPhoneNumbers(function() {
|
||||
phoneNumbers.forEach(function(phoneNumber, index) {
|
||||
$('#workflow-phone-numbers .phone-number-row').eq(index).find('select').val(phoneNumber);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Fallback to legacy phone number field
|
||||
$('#workflow-phone').val(phoneNumberToSelect);
|
||||
$('#workflow-phone').trigger('change');
|
||||
}
|
||||
});
|
||||
});
|
||||
updateWorkflowDisplay();
|
||||
} else {
|
||||
@@ -2386,6 +2446,36 @@ jQuery(document).ready(function($) {
|
||||
}
|
||||
};
|
||||
|
||||
// Phone Number Management for Workflows
|
||||
$(document).on('click', '.add-phone-number', function() {
|
||||
var phoneNumbers = [];
|
||||
var $container = $('#workflow-phone-numbers');
|
||||
|
||||
// Get available phone numbers from first select
|
||||
var $firstSelect = $container.find('select').first();
|
||||
var availableOptions = $firstSelect.html();
|
||||
|
||||
var newRow = '<div class="phone-number-row" style="margin-top: 10px;">' +
|
||||
'<select name="phone_numbers[]" class="workflow-phone-select">' + availableOptions + '</select>' +
|
||||
'<button type="button" class="button remove-phone-number" style="margin-left: 10px; background: #d63638; color: white;">Remove</button>' +
|
||||
'</div>';
|
||||
|
||||
$container.append(newRow);
|
||||
|
||||
// Update button text on first row
|
||||
$container.find('.add-phone-number').first().text('Add Another Number');
|
||||
});
|
||||
|
||||
$(document).on('click', '.remove-phone-number', function() {
|
||||
var $container = $('#workflow-phone-numbers');
|
||||
$(this).closest('.phone-number-row').remove();
|
||||
|
||||
// Update button text if only one row remains
|
||||
if ($container.find('.phone-number-row').length === 1) {
|
||||
$container.find('.add-phone-number').first().text('Add Number');
|
||||
}
|
||||
});
|
||||
|
||||
// Callback Management Functions
|
||||
window.requestCallback = function() {
|
||||
var phoneNumber = prompt('Enter phone number for callback (e.g., +1234567890):');
|
||||
|
Reference in New Issue
Block a user