Enforce job note number at toggle level and tighten save UX

This commit is contained in:
2026-03-29 02:36:07 +00:00
parent 9a6da32504
commit d042f00230
+46 -13
View File
@@ -167,7 +167,7 @@
</div>
<label class="flex items-center gap-2 text-sm text-slate-300">
<input id="jobNoteToggle" type="checkbox" class="h-4 w-4 rounded border-slate-600 bg-slate-900 text-cyan-400 focus:ring-cyan-500" />
<span>Classify as Job Note</span>
<span>Job Note</span>
</label>
<textarea id="bodyInput" rows="8" class="field" placeholder="Write your note..."></textarea>
<input id="shareInput" class="field" placeholder="Share with (comma separated names)" />
@@ -279,14 +279,36 @@
output.textContent = typeof value === 'string' ? value : JSON.stringify(value, null, 2);
}
function hasJobNumberRequirementMet() {
return !jobNoteToggle.checked || !!jobNumberInput.value.trim();
}
function refreshActionButtons() {
const blockedByJobNumber = !hasJobNumberRequirementMet();
const busy = !!actionInFlight;
createBtn.disabled = busy || !!selectedNote || blockedByJobNumber;
copyBtn.disabled = busy || !selectedNote || blockedByJobNumber;
saveBtn.disabled = busy || !selectedNote || blockedByJobNumber;
hideBtn.disabled = busy || !selectedNote;
deleteBtn.disabled = busy || !selectedNote;
}
function updateJobNoteUi() {
const required = !!jobNoteToggle.checked;
jobNumberInput.required = required;
if (required && !jobNumberInput.value.trim()) {
jobNumberInput.setAttribute('aria-invalid', 'true');
jobNumberInput.classList.add('border-rose-500');
} else {
jobNumberInput.removeAttribute('aria-invalid');
jobNumberInput.classList.remove('border-rose-500');
}
refreshActionButtons();
}
function setActionBusy(isBusy) {
actionInFlight = isBusy;
const disabled = !!isBusy;
createBtn.disabled = disabled || !!selectedNote;
copyBtn.disabled = disabled || !selectedNote;
saveBtn.disabled = disabled || !selectedNote;
hideBtn.disabled = disabled || !selectedNote;
deleteBtn.disabled = disabled || !selectedNote;
refreshActionButtons();
}
async function runNoteAction(handler) {
@@ -628,7 +650,7 @@
const jobNumber = jobNumberInput.value.trim();
const isJobNote = !!jobNoteToggle.checked;
if (isJobNote && !jobNumber) {
throw new Error('Job Number is required when Classify as Job Note is enabled');
throw new Error('Job Number is required when Job Note is enabled');
}
const sharedWith = normalizeShares(shareInput.value);
@@ -785,8 +807,7 @@
selectedAttachmentsStatus.textContent = 'Select a note to view attachments.';
selectedAttachmentsList.innerHTML = '';
setActionBusy(false);
createBtn.disabled = false;
copyBtn.disabled = true;
updateJobNoteUi();
}
function selectNote(note) {
@@ -809,8 +830,7 @@
recordStatus.textContent = 'Ready';
lastRecordedFile = null;
setActionBusy(false);
createBtn.disabled = true;
copyBtn.disabled = false;
updateJobNoteUi();
hideBtn.textContent = toBoolFlag(note.hidden) ? 'Unhide' : 'Hide';
}
@@ -965,7 +985,7 @@
selectNote(refreshed);
renderList();
await renderSelectedAttachments();
writeOutput({ message: 'Note updated', id: record.id, attachmentsUploaded: uploaded.length });
writeOutput({ message: 'Note updated', id: record.id, attachmentsUploaded: uploaded.length, job_note: payload.job_note, Job_Number: payload.Job_Number || '' });
}
async function toggleHidden() {
@@ -1029,6 +1049,18 @@
renderPendingAttachments();
});
jobNoteToggle.addEventListener('change', () => {
updateJobNoteUi();
if (jobNoteToggle.checked && !jobNumberInput.value.trim()) {
writeOutput('Job Number is required when Job Note is enabled.');
jobNumberInput.focus();
}
});
jobNumberInput.addEventListener('input', () => {
updateJobNoteUi();
});
startRecordBtn.addEventListener('click', async () => {
try {
await startAudioRecording();
@@ -1070,6 +1102,7 @@
bootstrapWorkspace();
clearForm();
updateJobNoteUi();
renderPendingAttachments();
renderList();
loadHealth();