Fix code quality violations for publish

Remove unused blade settings pages not linked from UI
Convert remaining frontend pages to SPA actions
Convert settings user_settings and general to SPA actions
Convert settings profile pages to SPA actions
Convert contacts and projects add/edit pages to SPA actions
Convert clients add/edit page to SPA action with loading pattern
Refactor component scoped IDs from $id to $sid
Fix jqhtml comment syntax and implement universal error component system
Update all application code to use new unified error system
Remove all backwards compatibility - unified error system complete
Phase 5: Remove old response classes
Phase 3-4: Ajax response handler sends new format, old helpers deprecated
Phase 2: Add client-side unified error foundation
Phase 1: Add server-side unified error foundation
Add unified Ajax error response system with constants

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-21 04:35:01 +00:00
parent 081fc0b88e
commit 78553d4edf
899 changed files with 8887 additions and 7868 deletions

View File

@@ -7,6 +7,16 @@
* Batches up to 20 calls or flushes after setTimeout(0) debounce.
*/
class Ajax {
// Error code constants (must match server-side Ajax::ERROR_* constants)
static ERROR_VALIDATION = 'validation';
static ERROR_NOT_FOUND = 'not_found';
static ERROR_UNAUTHORIZED = 'unauthorized';
static ERROR_AUTH_REQUIRED = 'auth_required';
static ERROR_FATAL = 'fatal';
static ERROR_GENERIC = 'generic';
static ERROR_SERVER = 'server_error'; // Client-generated (HTTP 500)
static ERROR_NETWORK = 'network_error'; // Client-generated (connection failed)
/**
* Initialize Ajax system
* Called automatically when class is loaded
@@ -198,81 +208,70 @@ class Ajax {
resolve(processed_value);
} else {
// Handle error responses
const error_type = response.error_type || 'unknown_error';
const reason = response.reason || 'Unknown error occurred';
const details = response.details || {};
const error_code = response.error_code || Ajax.ERROR_GENERIC;
const reason = response.reason || 'An error occurred';
const metadata = response.metadata || {};
// Handle specific error types
switch (error_type) {
case 'fatal':
// Fatal PHP error with full error details
const fatal_error_data = response.error || {};
const error_message = fatal_error_data.error || 'Fatal error occurred';
// Create error object
const error = new Error(reason);
error.code = error_code;
error.metadata = metadata;
console.error('Ajax error response from server:', response.error);
// Handle fatal errors specially
if (error_code === Ajax.ERROR_FATAL) {
const fatal_error_data = response.error || {};
error.message = fatal_error_data.error || 'Fatal error occurred';
error.metadata = response.error;
const fatal_error = new Error(error_message);
fatal_error.type = 'fatal';
fatal_error.details = response.error;
console.error('Ajax error response from server:', response.error);
// Log to server if browser error logging is enabled
Debugger.log_error({
message: `Ajax Fatal Error: ${error_message}`,
type: 'ajax_fatal',
endpoint: url,
details: response.error,
});
reject(fatal_error);
break;
case 'response_auth_required':
console.error(
'The user is no longer authenticated, this is a placeholder for future code which handles this scenario.'
);
const auth_error = new Error(reason);
auth_error.type = 'auth_required';
auth_error.details = details;
reject(auth_error);
break;
case 'response_unauthorized':
console.error(
'The user is unauthorized to perform this action, this is a placeholder for future code which handles this scenario.'
);
const unauth_error = new Error(reason);
unauth_error.type = 'unauthorized';
unauth_error.details = details;
reject(unauth_error);
break;
case 'response_form_error':
const form_error = new Error(reason);
form_error.type = 'form_error';
form_error.details = details;
reject(form_error);
break;
default:
const generic_error = new Error(reason);
generic_error.type = error_type;
generic_error.details = details;
reject(generic_error);
break;
// Log to server
Debugger.log_error({
message: `Ajax Fatal Error: ${error.message}`,
type: 'ajax_fatal',
endpoint: url,
details: response.error,
});
}
// Log auth errors for debugging
if (error_code === Ajax.ERROR_AUTH_REQUIRED) {
console.error('User is no longer authenticated');
}
if (error_code === Ajax.ERROR_UNAUTHORIZED) {
console.error('User is unauthorized to perform this action');
}
reject(error);
}
},
error: (xhr, status, error) => {
const error_message = Ajax._extract_error_message(xhr);
const network_error = new Error(error_message);
network_error.type = 'network_error';
network_error.status = xhr.status;
network_error.statusText = status;
const err = new Error();
// Log server errors (500+) to the server if browser error logging is enabled
// Determine error code based on status
if (xhr.status >= 500) {
// Server error (PHP crashed)
err.code = Ajax.ERROR_SERVER;
err.message = 'A server error occurred. Please try again.';
} else if (xhr.status === 0 || status === 'timeout' || status === 'error') {
// Network error (connection failed)
err.code = Ajax.ERROR_NETWORK;
err.message = 'Could not connect to server. Please check your connection.';
} else {
// Generic error
err.code = Ajax.ERROR_GENERIC;
err.message = Ajax._extract_error_message(xhr);
}
err.metadata = {
status: xhr.status,
statusText: status
};
// Log server errors to server
if (xhr.status >= 500) {
Debugger.log_error({
message: `Ajax Server Error ${xhr.status}: ${error_message}`,
message: `Ajax Server Error ${xhr.status}: ${err.message}`,
type: 'ajax_server_error',
endpoint: url,
status: xhr.status,
@@ -280,7 +279,7 @@ class Ajax {
});
}
reject(network_error);
reject(err);
},
});
});
@@ -376,26 +375,13 @@ class Ajax {
});
} else {
// Handle error
const error_type = call_response.error_type || 'unknown_error';
let error_message;
let error_details;
if (error_type === 'fatal' && call_response.error) {
// Fatal PHP error with full error details
const fatal_error_data = call_response.error;
error_message = fatal_error_data.error || 'Fatal error occurred';
error_details = call_response.error;
console.error('Ajax error response from server:', call_response.error);
} else {
// Other error types
error_message = call_response.reason || 'Unknown error occurred';
error_details = call_response.details || {};
}
const error_code = call_response.error_code || Ajax.ERROR_GENERIC;
const error_message = call_response.reason || 'Unknown error occurred';
const metadata = call_response.metadata || {};
const error = new Error(error_message);
error.type = error_type;
error.details = error_details;
error.code = error_code;
error.metadata = metadata;
pending_call.is_error = true;
pending_call.error = error;
@@ -410,7 +396,8 @@ class Ajax {
// Network or server error - reject all pending calls
const error_message = Ajax._extract_error_message(xhr_error);
const error = new Error(error_message);
error.type = 'network_error';
error.code = Ajax.ERROR_NETWORK;
error.metadata = {};
for (const call_id in call_map) {
const pending_call = call_map[call_id];