175 lines
5.0 KiB
JavaScript
175 lines
5.0 KiB
JavaScript
/**
|
|
* Toast Notification System
|
|
* Provides consistent, user-friendly notifications across the application
|
|
* Uses Toastr library with Bootstrap 5 theming
|
|
*/
|
|
|
|
// Configure Toastr global options
|
|
toastr.options = {
|
|
"closeButton": true,
|
|
"debug": false,
|
|
"newestOnTop": true,
|
|
"progressBar": true,
|
|
"positionClass": "toast-top-right",
|
|
"preventDuplicates": true,
|
|
"onclick": null,
|
|
"showDuration": "300",
|
|
"hideDuration": "1000",
|
|
"timeOut": "5000",
|
|
"extendedTimeOut": "1000",
|
|
"showEasing": "swing",
|
|
"hideEasing": "linear",
|
|
"showMethod": "fadeIn",
|
|
"hideMethod": "fadeOut"
|
|
};
|
|
|
|
/**
|
|
* Show success toast notification
|
|
* @param {string} message - The success message to display
|
|
* @param {string} title - Optional title for the toast
|
|
*/
|
|
function showSuccess(message, title = 'Success') {
|
|
toastr.success(message, title);
|
|
}
|
|
|
|
/**
|
|
* Show error toast notification
|
|
* @param {string} message - The error message to display
|
|
* @param {string} title - Optional title for the toast
|
|
*/
|
|
function showError(message, title = 'Error') {
|
|
toastr.error(message, title);
|
|
}
|
|
|
|
/**
|
|
* Show warning toast notification
|
|
* @param {string} message - The warning message to display
|
|
* @param {string} title - Optional title for the toast
|
|
*/
|
|
function showWarning(message, title = 'Warning') {
|
|
toastr.warning(message, title);
|
|
}
|
|
|
|
/**
|
|
* Show info toast notification
|
|
* @param {string} message - The info message to display
|
|
* @param {string} title - Optional title for the toast
|
|
*/
|
|
function showInfo(message, title = 'Info') {
|
|
toastr.info(message, title);
|
|
}
|
|
|
|
/**
|
|
* Show validation errors from ModelState
|
|
* @param {Array<string>} errors - Array of validation error messages
|
|
*/
|
|
function showValidationErrors(errors) {
|
|
if (!errors || errors.length === 0) return;
|
|
|
|
// If single error, show it directly
|
|
if (errors.length === 1) {
|
|
showError(errors[0], 'Validation Error');
|
|
return;
|
|
}
|
|
|
|
// Multiple errors - show as a list
|
|
const errorList = '<ul class="mb-0 ps-3">' +
|
|
errors.map(err => `<li>${escapeHtml(err)}</li>`).join('') +
|
|
'</ul>';
|
|
|
|
toastr.error(errorList, `${errors.length} Validation Errors`, {
|
|
timeOut: 8000,
|
|
extendedTimeOut: 2000
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Display TempData messages automatically on page load
|
|
* Expects TempData keys: Success, Error, Warning, Info
|
|
*/
|
|
function displayTempDataMessages() {
|
|
// Success message
|
|
const successMsg = document.getElementById('tempdata-success-message');
|
|
if (successMsg && successMsg.textContent.trim()) {
|
|
showSuccess(successMsg.textContent.trim());
|
|
}
|
|
|
|
// Error message
|
|
const errorMsg = document.getElementById('tempdata-error-message');
|
|
if (errorMsg && errorMsg.textContent.trim()) {
|
|
showError(errorMsg.textContent.trim());
|
|
}
|
|
|
|
// Permanent success — no auto-dismiss
|
|
const successPerm = document.getElementById('tempdata-success-permanent-message');
|
|
if (successPerm && successPerm.textContent.trim()) {
|
|
toastr.success(successPerm.textContent.trim(), 'Success', { timeOut: 0, extendedTimeOut: 0 });
|
|
}
|
|
|
|
// Permanent error — no auto-dismiss
|
|
const errorPerm = document.getElementById('tempdata-error-permanent-message');
|
|
if (errorPerm && errorPerm.textContent.trim()) {
|
|
toastr.error(errorPerm.textContent.trim(), 'Error', { timeOut: 0, extendedTimeOut: 0 });
|
|
}
|
|
|
|
// Warning message
|
|
const warningMsg = document.getElementById('tempdata-warning-message');
|
|
if (warningMsg && warningMsg.textContent.trim()) {
|
|
showWarning(warningMsg.textContent.trim());
|
|
}
|
|
|
|
// Info message
|
|
const infoMsg = document.getElementById('tempdata-info-message');
|
|
if (infoMsg && infoMsg.textContent.trim()) {
|
|
showInfo(infoMsg.textContent.trim());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Display ModelState validation errors on page load
|
|
* Expects a hidden div with id 'modelstate-errors' containing JSON array of errors
|
|
*/
|
|
function displayModelStateErrors() {
|
|
const errorContainer = document.getElementById('modelstate-errors');
|
|
if (errorContainer && errorContainer.textContent.trim()) {
|
|
try {
|
|
const errors = JSON.parse(errorContainer.textContent);
|
|
showValidationErrors(errors);
|
|
} catch (e) {
|
|
console.error('Failed to parse ModelState errors:', e);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Escape HTML to prevent XSS
|
|
* @param {string} text - Text to escape
|
|
* @returns {string} - Escaped text
|
|
*/
|
|
function escapeHtml(text) {
|
|
const div = document.createElement('div');
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
}
|
|
|
|
/**
|
|
* Clear all toasts
|
|
*/
|
|
function clearAllToasts() {
|
|
toastr.clear();
|
|
}
|
|
|
|
// Auto-initialize on page load
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
displayTempDataMessages();
|
|
displayModelStateErrors();
|
|
});
|
|
|
|
// Make functions globally available
|
|
window.showSuccess = showSuccess;
|
|
window.showError = showError;
|
|
window.showWarning = showWarning;
|
|
window.showInfo = showInfo;
|
|
window.showValidationErrors = showValidationErrors;
|
|
window.clearAllToasts = clearAllToasts;
|