landscape-platform/app/Components/SoftDelete/resources/js/soft-delete-conflict-handler.js
2025-03-13 19:50:56 -05:00

128 lines
4.3 KiB
JavaScript

/**
* Soft Delete Conflict Handler
*
* This module handles the detection and resolution of soft delete conflicts.
* Save this file to public/js/soft-delete-conflict-handler.js
*/
const SoftDeleteConflictHandler = {
/**
* Initialize the handler for a specific form.
*
* @param {string} formSelector - The CSS selector for the form
* @param {string} modelClass - The fully qualified class name of the model
* @param {object} options - Additional options
*/
init: function(formSelector, modelClass, options = {}) {
const form = document.querySelector(formSelector);
if (!form) {
console.error(`Form not found: ${formSelector}`);
return;
}
// Store the model class on the form for later use
form.dataset.modelClass = modelClass;
// Set success and cancel redirect URLs if provided
if (options.successRedirect) {
form.dataset.successRedirect = options.successRedirect;
}
if (options.cancelRedirect) {
form.dataset.cancelRedirect = options.cancelRedirect;
}
// Intercept form submission
form.addEventListener('submit', (event) => {
// Don't prevent submission if we've already checked for conflicts
if (form.dataset.conflictChecked === 'true') {
return true;
}
// Prevent the default form submission
event.preventDefault();
// Check for conflicts
this.checkForConflicts(form, modelClass, (hasConflict, conflictData) => {
if (hasConflict) {
// Show the conflict resolution modal
this.showConflictModal(conflictData, form);
} else {
// No conflict, continue with form submission
form.dataset.conflictChecked = 'true';
form.submit();
}
});
});
},
/**
* Check for soft delete conflicts before form submission.
*
* @param {HTMLFormElement} form - The form element
* @param {string} modelClass - The fully qualified class name of the model
* @param {Function} callback - Callback function to handle the result
*/
checkForConflicts: function(form, modelClass, callback) {
// Create a FormData object from the form
const formData = new FormData(form);
// Add the model class
formData.append('model_class', modelClass);
// Send the request to check for conflicts
fetch('/admin/soft-delete/check-conflict', {
method: 'POST',
body: formData,
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'Accept': 'application/json',
},
})
.then(response => response.json())
.then(data => {
if (data.success && data.conflict) {
// Conflict found
callback(true, data.duplicate);
} else {
// No conflict
callback(false, null);
}
})
.catch(error => {
console.error('Error checking for conflicts:', error);
// On error, allow the form to submit to let server-side validation handle it
callback(false, null);
});
},
/**
* Show the conflict resolution modal.
*
* @param {object} conflictData - Data about the conflicting record
* @param {HTMLFormElement} form - The form element
*/
showConflictModal: function(conflictData, form) {
// Get form data as an object
const formDataObj = {};
const formData = new FormData(form);
for (const [key, value] of formData.entries()) {
formDataObj[key] = value;
}
// Dispatch a custom event to open the modal
window.dispatchEvent(new CustomEvent('open-soft-delete-modal', {
detail: {
conflict: conflictData,
formData: formDataObj,
formElement: form,
modelClass: form.dataset.modelClass
}
}));
}
};
// Expose to window for global access
window.SoftDeleteConflictHandler = SoftDeleteConflictHandler;