From 595cf6ac8aaf3b36e3428241693aaf172708bab2 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Thu, 9 Jul 2026 21:08:42 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20=EB=B9=84?= =?UTF-8?q?=EB=8F=99=EA=B8=B0=20=EC=9E=91=EC=97=85=20=EB=B2=84=ED=8A=BC?= =?UTF-8?q?=EC=97=90=20=EC=9D=B8=EB=9D=BC=EC=9D=B8=20=EB=A1=9C=EB=94=A9=20?= =?UTF-8?q?=ED=85=8D=EC=8A=A4=ED=8A=B8=20=ED=94=BC=EB=93=9C=EB=B0=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 문서 업로드 및 재시도와 같은 비동기 작업 중 버튼의 innerHTML을 일시적으로 'Submitting...' 및 'Requesting retry...'로 변경하여 진행 상태에 대한 즉각적인 피드백을 제공합니다. - 네트워크 요청이 완료되면 finally 블록에서 버튼의 원래 HTML 구성을 안전하게 복원합니다. - 사용자의 중복 클릭을 방지하고 시스템의 반응성을 높여 UX를 개선합니다. --- .jules/palette.md | 3 +++ src/main/resources/static/assets/viewer/demo.js | 6 ++++++ .../viewer/controller/ViewerUiControllerTest.java | 1 + 3 files changed, 10 insertions(+) diff --git a/.jules/palette.md b/.jules/palette.md index a1633627..820f33d1 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -1,3 +1,6 @@ ## 2024-05-18 - Disabled and Loading States for Async Actions **Learning:** Adding explicit loading and disabled states to asynchronous action buttons (like "Refresh") provides immediate feedback, reducing user confusion and preventing double-submissions. **Action:** Always ensure that buttons triggering network requests visually indicate the loading state and are disabled until the request completes. +## 2026-07-09 - 버튼 내 로딩 텍스트 +**Learning:** 비동기 작업 시 버튼 HTML을 임시로 로딩 텍스트로 교체하여 진행 상태를 시각적으로 보여주는 것은 사용자 경험(UX)을 크게 향상시킵니다. +**Action:** 비동기 작업을 시작하기 전에 버튼의 원래 innerHTML을 저장하고, 진행 상태를 나타내도록 HTML을 업데이트한 뒤, finally 블록에서 원래 HTML로 복원합니다. diff --git a/src/main/resources/static/assets/viewer/demo.js b/src/main/resources/static/assets/viewer/demo.js index 84eb8f3a..d6c7d6c8 100644 --- a/src/main/resources/static/assets/viewer/demo.js +++ b/src/main/resources/static/assets/viewer/demo.js @@ -271,6 +271,8 @@ async function retryActiveJob() { const jobId = activeJobDetail.jobId; setStatus("Requesting operator retry..."); el.retryJobBtn.disabled = true; + const originalRetryHtml = el.retryJobBtn.innerHTML; + el.retryJobBtn.innerHTML = "Requesting retry..."; try { const res = await fetch(`/api/v1/convert/jobs/${encodeURIComponent(jobId)}/retry`, { method: "POST", @@ -308,6 +310,7 @@ async function retryActiveJob() { setError("Network error while requesting retry. Retry when the service is reachable."); } finally { el.retryJobBtn.disabled = false; + el.retryJobBtn.innerHTML = originalRetryHtml; } } @@ -437,6 +440,8 @@ async function submitDocument(event) { el.submitBtn.disabled = true; setStatus("Submitting document..."); + const originalBtnHtml = el.submitBtn.innerHTML; + el.submitBtn.innerHTML = "Submitting..."; try { const body = new FormData(); @@ -479,6 +484,7 @@ async function submitDocument(event) { setError("Network error while submitting. Retry when the service is reachable."); } finally { el.submitBtn.disabled = false; + el.submitBtn.innerHTML = originalBtnHtml; } } diff --git a/src/test/java/com/clearfolio/viewer/controller/ViewerUiControllerTest.java b/src/test/java/com/clearfolio/viewer/controller/ViewerUiControllerTest.java index dadb8949..c244b173 100644 --- a/src/test/java/com/clearfolio/viewer/controller/ViewerUiControllerTest.java +++ b/src/test/java/com/clearfolio/viewer/controller/ViewerUiControllerTest.java @@ -116,6 +116,7 @@ void demoScriptUsesExistingApiAndSessionHistory() throws Exception { assertTrue(script.contains("lastInspectedAt")); assertTrue(script.contains("openJobDetail")); assertTrue(script.contains("retryActiveJob")); + assertTrue(script.contains("innerHTML")); assertTrue(script.contains("/retry")); assertTrue(script.contains("X-Clearfolio-Operator-Id")); assertTrue(script.contains("X-Clearfolio-Tenant-Id")); From 879e21d13418183787b609ac67ee386afda59f66 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Thu, 9 Jul 2026 21:23:41 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20=EB=B9=84?= =?UTF-8?q?=EB=8F=99=EA=B8=B0=20=EC=9E=91=EC=97=85=20=EB=B2=84=ED=8A=BC?= =?UTF-8?q?=EC=97=90=20=EC=9D=B8=EB=9D=BC=EC=9D=B8=20=EB=A1=9C=EB=94=A9=20?= =?UTF-8?q?=ED=85=8D=EC=8A=A4=ED=8A=B8=20=ED=94=BC=EB=93=9C=EB=B0=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 문서 업로드 및 재시도와 같은 비동기 작업 중 버튼의 innerHTML을 일시적으로 'Submitting...' 및 'Requesting retry...'로 변경하여 진행 상태에 대한 즉각적인 피드백을 제공합니다. - 네트워크 요청이 완료되면 finally 블록에서 버튼의 원래 HTML 구성을 안전하게 복원합니다. - 사용자의 중복 클릭을 방지하고 시스템의 반응성을 높여 UX를 개선합니다.