128 lines
4.3 KiB
JavaScript
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;
|