Miscellaneous UI and pricing updates from prior sessions
- PricingCalculationService: powder coverage and specific gravity math fixes - Dashboard/Index: minor widget updates - Jobs/Details, Jobs/Intake: shop floor and intake view improvements - Quotes/Details: detail view updates - GiftCertificates/Details: detail view update - job-photos.js: photo gallery improvements Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ const jobPhotoModule = {
|
||||
allPhotos: [],
|
||||
currentPhotoIndex: 0,
|
||||
_tagApi: null,
|
||||
_editTagApi: null,
|
||||
|
||||
init: function(jobId, tagSuggestions) {
|
||||
this.jobId = jobId;
|
||||
@@ -21,6 +22,17 @@ const jobPhotoModule = {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Reset to view mode when the view modal closes
|
||||
const viewModal = document.getElementById('viewPhotoModal');
|
||||
if (viewModal) {
|
||||
viewModal.addEventListener('hidden.bs.modal', () => {
|
||||
const editPanel = document.getElementById('photoEditPanel');
|
||||
if (editPanel && !editPanel.classList.contains('d-none')) {
|
||||
this.cancelPhotoEdit();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
loadJobPhotos: function() {
|
||||
@@ -119,6 +131,11 @@ const jobPhotoModule = {
|
||||
},
|
||||
|
||||
navigatePhoto: function(direction) {
|
||||
// Exit edit mode before navigating to another photo
|
||||
const editPanel = document.getElementById('photoEditPanel');
|
||||
if (editPanel && !editPanel.classList.contains('d-none')) {
|
||||
this.cancelPhotoEdit();
|
||||
}
|
||||
this.currentPhotoIndex += direction;
|
||||
if (this.currentPhotoIndex < 0) this.currentPhotoIndex = this.allPhotos.length - 1;
|
||||
if (this.currentPhotoIndex >= this.allPhotos.length) this.currentPhotoIndex = 0;
|
||||
@@ -212,6 +229,73 @@ const jobPhotoModule = {
|
||||
});
|
||||
},
|
||||
|
||||
editPhoto: function() {
|
||||
const photo = this.allPhotos[this.currentPhotoIndex];
|
||||
document.getElementById('editPhotoType').value = photo.photoType;
|
||||
document.getElementById('editPhotoCaption').value = photo.caption || '';
|
||||
// Pre-populate tag hidden field so initTagInput picks it up
|
||||
document.getElementById('editPhotoTagsHidden').value = photo.tags || '';
|
||||
this._editTagApi = initTagInput('editPhotoTagsHidden', 'editPhotoTagsContainer', {
|
||||
suggestions: this._tagSuggestions
|
||||
});
|
||||
document.getElementById('photoDetails').classList.add('d-none');
|
||||
document.getElementById('photoEditPanel').classList.remove('d-none');
|
||||
document.getElementById('viewModeButtons').classList.add('d-none');
|
||||
document.getElementById('editModeButtons').classList.remove('d-none');
|
||||
},
|
||||
|
||||
cancelPhotoEdit: function() {
|
||||
document.getElementById('photoEditPanel').classList.add('d-none');
|
||||
document.getElementById('photoDetails').classList.remove('d-none');
|
||||
document.getElementById('editModeButtons').classList.add('d-none');
|
||||
document.getElementById('viewModeButtons').classList.remove('d-none');
|
||||
},
|
||||
|
||||
savePhotoEdit: function() {
|
||||
const photo = this.allPhotos[this.currentPhotoIndex];
|
||||
const photoType = parseInt(document.getElementById('editPhotoType').value, 10);
|
||||
const caption = document.getElementById('editPhotoCaption').value.trim();
|
||||
const tags = document.getElementById('editPhotoTagsHidden').value;
|
||||
const token = document.querySelector('input[name="__RequestVerificationToken"]').value;
|
||||
|
||||
fetch('/Jobs/UpdatePhoto', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'RequestVerificationToken': token
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: photo.id,
|
||||
caption: caption,
|
||||
photoType: photoType,
|
||||
tags: tags,
|
||||
displayOrder: photo.displayOrder || 0
|
||||
})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
photo.caption = caption || null;
|
||||
photo.photoType = photoType;
|
||||
photo.photoTypeDisplay = this.getPhotoTypeLabel(photoType);
|
||||
photo.tags = tags || null;
|
||||
photo.tagsList = tags ? tags.split(',').map(t => t.trim()).filter(t => t) : [];
|
||||
this.cancelPhotoEdit();
|
||||
this.viewPhoto(this.currentPhotoIndex, true);
|
||||
this.renderPhotoGallery(this.allPhotos);
|
||||
this.showToast('Photo updated successfully', 'success');
|
||||
} else {
|
||||
this.showToast(data.message || 'Error updating photo', 'danger');
|
||||
}
|
||||
})
|
||||
.catch(() => this.showToast('An error occurred while updating', 'danger'));
|
||||
},
|
||||
|
||||
getPhotoTypeLabel: function(type) {
|
||||
const labels = { 0: 'Before', 1: 'Progress', 2: 'After', 3: 'Quality Check', 4: 'Issue', 5: 'Completed' };
|
||||
return labels[type] || 'Unknown';
|
||||
},
|
||||
|
||||
setupDragDrop: function() {
|
||||
const dropZone = document.getElementById('dropZone');
|
||||
const fileInput = document.getElementById('photoFile');
|
||||
|
||||
Reference in New Issue
Block a user