// Modal Management for Lookup Tables // This file contains modal-specific functions that replace the old prompt() dialogs // Include this AFTER company-settings-lookups.js (function() { 'use strict'; // ==================== // JOB STATUS MODAL // ==================== window.showJobStatusModal = function(item) { const modal = new bootstrap.Modal(document.getElementById('jobStatusModal')); const form = document.getElementById('jobStatusForm'); // Reset form form.reset(); document.getElementById('jobStatusId').value = ''; if (item) { // Edit mode document.getElementById('jobStatusModalTitle').textContent = 'Edit Job Status'; document.getElementById('jobStatusId').value = item.id; document.getElementById('jobStatusCode').value = item.statusCode; document.getElementById('jobStatusCode').disabled = true; // Cannot change code document.getElementById('jobStatusDisplayName').value = item.displayName; document.getElementById('jobStatusColorClass').value = item.colorClass; document.getElementById('jobStatusCategory').value = item.workflowCategory || ''; document.getElementById('jobStatusIsTerminal').checked = item.isTerminalStatus; document.getElementById('jobStatusIsWIP').checked = item.isWorkInProgressStatus; document.getElementById('jobStatusDescription').value = item.description || ''; } else { // Add mode document.getElementById('jobStatusModalTitle').textContent = 'Add Job Status'; document.getElementById('jobStatusCode').disabled = false; } modal.show(); }; document.getElementById('saveJobStatusBtn').addEventListener('click', function() { const form = document.getElementById('jobStatusForm'); if (!form.checkValidity()) { form.reportValidity(); return; } const id = document.getElementById('jobStatusId').value; const data = { statusCode: document.getElementById('jobStatusCode').value.toUpperCase(), displayName: document.getElementById('jobStatusDisplayName').value, colorClass: document.getElementById('jobStatusColorClass').value, workflowCategory: document.getElementById('jobStatusCategory').value || null, isTerminalStatus: document.getElementById('jobStatusIsTerminal').checked, isWorkInProgressStatus: document.getElementById('jobStatusIsWIP').checked, description: document.getElementById('jobStatusDescription').value || null, displayOrder: 999 // Will be set by server }; if (id) { // Update data.id = parseInt(id); data.isActive = true; $.ajax({ url: '/CompanySettings/UpdateJobStatus', type: 'POST', contentType: 'application/json', data: JSON.stringify(data), success: function(response) { if (response.success) { bootstrap.Modal.getInstance(document.getElementById('jobStatusModal')).hide(); window.showToast('success', response.message); window.loadJobStatuses(); } else { window.showToast('error', response.message); } }, error: function() { window.showToast('error', 'Failed to update job status'); } }); } else { // Create $.ajax({ url: '/CompanySettings/CreateJobStatus', type: 'POST', contentType: 'application/json', data: JSON.stringify(data), success: function(response) { if (response.success) { bootstrap.Modal.getInstance(document.getElementById('jobStatusModal')).hide(); window.showToast('success', response.message); window.loadJobStatuses(); } else { window.showToast('error', response.message); } }, error: function() { window.showToast('error', 'Failed to create job status'); } }); } }); // ==================== // JOB PRIORITY MODAL // ==================== window.showJobPriorityModal = function(item) { const modal = new bootstrap.Modal(document.getElementById('jobPriorityModal')); const form = document.getElementById('jobPriorityForm'); // Reset form form.reset(); document.getElementById('jobPriorityId').value = ''; if (item) { // Edit mode document.getElementById('jobPriorityModalTitle').textContent = 'Edit Job Priority'; document.getElementById('jobPriorityId').value = item.id; document.getElementById('jobPriorityCode').value = item.priorityCode; document.getElementById('jobPriorityCode').disabled = true; // Cannot change code document.getElementById('jobPriorityDisplayName').value = item.displayName; document.getElementById('jobPriorityColorClass').value = item.colorClass; document.getElementById('jobPriorityDescription').value = item.description || ''; } else { // Add mode document.getElementById('jobPriorityModalTitle').textContent = 'Add Job Priority'; document.getElementById('jobPriorityCode').disabled = false; } modal.show(); }; document.getElementById('saveJobPriorityBtn').addEventListener('click', function() { const form = document.getElementById('jobPriorityForm'); if (!form.checkValidity()) { form.reportValidity(); return; } const id = document.getElementById('jobPriorityId').value; const data = { priorityCode: document.getElementById('jobPriorityCode').value.toUpperCase(), displayName: document.getElementById('jobPriorityDisplayName').value, colorClass: document.getElementById('jobPriorityColorClass').value, description: document.getElementById('jobPriorityDescription').value || null, displayOrder: 999 // Will be set by server }; if (id) { // Update data.id = parseInt(id); data.isActive = true; $.ajax({ url: '/CompanySettings/UpdateJobPriority', type: 'POST', contentType: 'application/json', data: JSON.stringify(data), success: function(response) { if (response.success) { bootstrap.Modal.getInstance(document.getElementById('jobPriorityModal')).hide(); window.showToast('success', response.message); window.loadJobPriorities(); } else { window.showToast('error', response.message); } }, error: function() { window.showToast('error', 'Failed to update job priority'); } }); } else { // Create $.ajax({ url: '/CompanySettings/CreateJobPriority', type: 'POST', contentType: 'application/json', data: JSON.stringify(data), success: function(response) { if (response.success) { bootstrap.Modal.getInstance(document.getElementById('jobPriorityModal')).hide(); window.showToast('success', response.message); window.loadJobPriorities(); } else { window.showToast('error', response.message); } }, error: function() { window.showToast('error', 'Failed to create job priority'); } }); } }); // ==================== // QUOTE STATUS MODAL // ==================== window.showQuoteStatusModal = function(item) { const modal = new bootstrap.Modal(document.getElementById('quoteStatusModal')); const form = document.getElementById('quoteStatusForm'); // Reset form form.reset(); document.getElementById('quoteStatusId').value = ''; if (item) { // Edit mode document.getElementById('quoteStatusModalTitle').textContent = 'Edit Quote Status'; document.getElementById('quoteStatusId').value = item.id; document.getElementById('quoteStatusCode').value = item.statusCode; document.getElementById('quoteStatusCode').disabled = true; // Cannot change code document.getElementById('quoteStatusDisplayName').value = item.displayName; document.getElementById('quoteStatusColorClass').value = item.colorClass; document.getElementById('quoteStatusIsApproved').checked = item.isApprovedStatus; document.getElementById('quoteStatusIsConverted').checked = item.isConvertedStatus; document.getElementById('quoteStatusIsDraft').checked = item.isDraftStatus; document.getElementById('quoteStatusDescription').value = item.description || ''; } else { // Add mode document.getElementById('quoteStatusModalTitle').textContent = 'Add Quote Status'; document.getElementById('quoteStatusCode').disabled = false; } modal.show(); }; document.getElementById('saveQuoteStatusBtn').addEventListener('click', function() { const form = document.getElementById('quoteStatusForm'); if (!form.checkValidity()) { form.reportValidity(); return; } const id = document.getElementById('quoteStatusId').value; const data = { statusCode: document.getElementById('quoteStatusCode').value.toUpperCase(), displayName: document.getElementById('quoteStatusDisplayName').value, colorClass: document.getElementById('quoteStatusColorClass').value, isApprovedStatus: document.getElementById('quoteStatusIsApproved').checked, isConvertedStatus: document.getElementById('quoteStatusIsConverted').checked, isDraftStatus: document.getElementById('quoteStatusIsDraft').checked, description: document.getElementById('quoteStatusDescription').value || null, displayOrder: 999 // Will be set by server }; if (id) { // Update data.id = parseInt(id); data.isActive = true; $.ajax({ url: '/CompanySettings/UpdateQuoteStatus', type: 'POST', contentType: 'application/json', data: JSON.stringify(data), success: function(response) { if (response.success) { bootstrap.Modal.getInstance(document.getElementById('quoteStatusModal')).hide(); window.showToast('success', response.message); window.loadQuoteStatuses(); } else { window.showToast('error', response.message); } }, error: function() { window.showToast('error', 'Failed to update quote status'); } }); } else { // Create $.ajax({ url: '/CompanySettings/CreateQuoteStatus', type: 'POST', contentType: 'application/json', data: JSON.stringify(data), success: function(response) { if (response.success) { bootstrap.Modal.getInstance(document.getElementById('quoteStatusModal')).hide(); window.showToast('success', response.message); window.loadQuoteStatuses(); } else { window.showToast('error', response.message); } }, error: function() { window.showToast('error', 'Failed to create quote status'); } }); } }); // ==================== // INVENTORY CATEGORY MODAL // ==================== window.showInventoryCategoryModal = function(item) { const modal = new bootstrap.Modal(document.getElementById('inventoryCategoryModal')); const form = document.getElementById('inventoryCategoryForm'); // Reset form form.reset(); document.getElementById('inventoryCategoryId').value = ''; if (item) { // Edit mode document.getElementById('inventoryCategoryModalTitle').textContent = 'Edit Inventory Category'; document.getElementById('inventoryCategoryId').value = item.id; document.getElementById('inventoryCategoryCode').value = item.categoryCode; document.getElementById('inventoryCategoryCode').disabled = true; // Cannot change code document.getElementById('inventoryCategoryDisplayName').value = item.displayName; document.getElementById('inventoryCategoryIsCoating').checked = item.isCoating; document.getElementById('inventoryCategoryDescription').value = item.description || ''; } else { // Add mode document.getElementById('inventoryCategoryModalTitle').textContent = 'Add Inventory Category'; document.getElementById('inventoryCategoryCode').disabled = false; } modal.show(); }; document.getElementById('saveInventoryCategoryBtn').addEventListener('click', function() { const form = document.getElementById('inventoryCategoryForm'); if (!form.checkValidity()) { form.reportValidity(); return; } const id = document.getElementById('inventoryCategoryId').value; const data = { categoryCode: document.getElementById('inventoryCategoryCode').value.toUpperCase(), displayName: document.getElementById('inventoryCategoryDisplayName').value, isCoating: document.getElementById('inventoryCategoryIsCoating').checked, description: document.getElementById('inventoryCategoryDescription').value || null, displayOrder: 999 // Will be set by server }; if (id) { // Update data.id = parseInt(id); data.isActive = true; $.ajax({ url: '/CompanySettings/UpdateInventoryCategory', type: 'POST', contentType: 'application/json', data: JSON.stringify(data), success: function(response) { if (response.success) { bootstrap.Modal.getInstance(document.getElementById('inventoryCategoryModal')).hide(); window.showToast('success', response.message); window.loadInventoryCategories(); } else { window.showToast('error', response.message); } }, error: function() { window.showToast('error', 'Failed to update inventory category'); } }); } else { // Create $.ajax({ url: '/CompanySettings/CreateInventoryCategory', type: 'POST', contentType: 'application/json', data: JSON.stringify(data), success: function(response) { if (response.success) { bootstrap.Modal.getInstance(document.getElementById('inventoryCategoryModal')).hide(); window.showToast('success', response.message); window.loadInventoryCategories(); } else { window.showToast('error', response.message); } }, error: function() { window.showToast('error', 'Failed to create inventory category'); } }); } }); // Update the window-level edit functions to use the new modals const originalEditJobStatus = window.editJobStatus; window.editJobStatus = function(id) { // Find the item from the global arrays const item = window.jobStatuses ? window.jobStatuses.find(s => s.id === id) : null; if (item) window.showJobStatusModal(item); }; const originalEditJobPriority = window.editJobPriority; window.editJobPriority = function(id) { const item = window.jobPriorities ? window.jobPriorities.find(p => p.id === id) : null; if (item) window.showJobPriorityModal(item); }; const originalEditQuoteStatus = window.editQuoteStatus; window.editQuoteStatus = function(id) { const item = window.quoteStatuses ? window.quoteStatuses.find(s => s.id === id) : null; if (item) window.showQuoteStatusModal(item); }; const originalEditInventoryCategory = window.editInventoryCategory; window.editInventoryCategory = function(id) { const item = window.inventoryCategories ? window.inventoryCategories.find(c => c.id === id) : null; if (item) window.showInventoryCategoryModal(item); }; // ==================== // APPOINTMENT TYPE MODAL // ==================== window.showAppointmentTypeModal = function(item) { const modal = new bootstrap.Modal(document.getElementById('appointmentTypeModal')); const form = document.getElementById('appointmentTypeForm'); // Reset form form.reset(); document.getElementById('appointmentTypeId').value = ''; document.getElementById('appointmentTypeActiveField').style.display = 'none'; if (item) { // Edit mode document.getElementById('appointmentTypeModalTitle').textContent = 'Edit Appointment Type'; document.getElementById('appointmentTypeId').value = item.id; document.getElementById('appointmentTypeCode').value = item.typeCode; document.getElementById('appointmentTypeCode').disabled = true; // Cannot change code document.getElementById('appointmentTypeDisplayName').value = item.displayName; document.getElementById('appointmentTypeColorClass').value = item.colorClass; document.getElementById('appointmentTypeIconClass').value = item.iconClass || ''; document.getElementById('appointmentTypeRequiresJob').checked = item.requiresJobLink; document.getElementById('appointmentTypeIsActive').checked = item.isActive; document.getElementById('appointmentTypeDescription').value = item.description || ''; document.getElementById('appointmentTypeActiveField').style.display = 'block'; } else { // Add mode document.getElementById('appointmentTypeModalTitle').textContent = 'Add Appointment Type'; document.getElementById('appointmentTypeCode').disabled = false; document.getElementById('appointmentTypeIsActive').checked = true; } modal.show(); // Update color preview after modal is shown window.updateAppointmentTypeColorPreview(); }; // Update the appointment type color preview badge window.updateAppointmentTypeColorPreview = function() { const colorSelect = document.getElementById('appointmentTypeColorClass'); const previewBadge = document.getElementById('appointmentTypeColorPreview'); if (!colorSelect || !previewBadge) return; const selectedColor = colorSelect.value; // Remove all existing Bootstrap color classes const colorClasses = [ 'bg-purple', 'bg-green', 'bg-blue', 'bg-orange', 'bg-red', 'bg-yellow', 'bg-pink', 'bg-cyan', 'bg-teal', 'bg-indigo', 'bg-lime', 'bg-brown', 'bg-gray', 'bg-success', 'bg-danger', 'bg-warning', 'bg-info', 'bg-primary', 'bg-secondary', 'bg-dark', 'text-dark', 'text-white' ]; previewBadge.classList.remove(...colorClasses); // Add the selected color class previewBadge.classList.add('bg-' + selectedColor); // Add text-dark for warning (yellow) to ensure visibility if (selectedColor === 'warning' || selectedColor === 'yellow' || selectedColor === 'lime') { previewBadge.classList.add('text-dark'); } else { previewBadge.classList.add('text-white'); } }; document.getElementById('saveAppointmentTypeBtn').addEventListener('click', function() { const form = document.getElementById('appointmentTypeForm'); if (!form.checkValidity()) { form.reportValidity(); return; } const id = document.getElementById('appointmentTypeId').value; const data = { typeCode: document.getElementById('appointmentTypeCode').value.toUpperCase(), displayName: document.getElementById('appointmentTypeDisplayName').value, colorClass: document.getElementById('appointmentTypeColorClass').value, iconClass: document.getElementById('appointmentTypeIconClass').value || null, requiresJobLink: document.getElementById('appointmentTypeRequiresJob').checked, description: document.getElementById('appointmentTypeDescription').value || null, displayOrder: 999 // Will be set by server }; if (id) { // Update data.id = parseInt(id); data.isActive = document.getElementById('appointmentTypeIsActive').checked; $.ajax({ url: '/CompanySettings/UpdateAppointmentType', type: 'POST', contentType: 'application/json', headers: { 'RequestVerificationToken': $('input[name="__RequestVerificationToken"]').val() }, data: JSON.stringify(data), success: function(response) { if (response.success) { bootstrap.Modal.getInstance(document.getElementById('appointmentTypeModal')).hide(); window.showToast('success', response.message); window.loadAppointmentTypes(); } else { window.showToast('error', response.message); } }, error: function() { window.showToast('error', 'Failed to update appointment type'); } }); } else { // Create $.ajax({ url: '/CompanySettings/CreateAppointmentType', type: 'POST', contentType: 'application/json', headers: { 'RequestVerificationToken': $('input[name="__RequestVerificationToken"]').val() }, data: JSON.stringify(data), success: function(response) { if (response.success) { bootstrap.Modal.getInstance(document.getElementById('appointmentTypeModal')).hide(); window.showToast('success', response.message); window.loadAppointmentTypes(); } else { window.showToast('error', response.message); } }, error: function() { window.showToast('error', 'Failed to create appointment type'); } }); } }); // Override the editAppointmentType function to use modal window.editAppointmentType = function(id) { const item = window.appointmentTypes ? window.appointmentTypes.find(t => t.id === id) : null; if (item) window.showAppointmentTypeModal(item); }; })();