From d042f002303be5416c9986c2c117988298d8b511 Mon Sep 17 00:00:00 2001 From: aewing Date: Sun, 29 Mar 2026 02:36:07 +0000 Subject: [PATCH] Enforce job note number at toggle level and tighten save UX --- notes-workspace.html | 59 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/notes-workspace.html b/notes-workspace.html index c84efab..78bb1d0 100644 --- a/notes-workspace.html +++ b/notes-workspace.html @@ -167,7 +167,7 @@ @@ -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();