Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .jules/palette.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
## 2026-07-13 - Async Table Actions UX
**Learning:** Adding explicit loading and disabled states to table action buttons that invoke asynchronous processes helps prevent redundant API calls and visually assures the user that their request is being handled.
**Action:** Consistently apply `disabled` state and `Loading...` text changes to inline table action buttons linked to async workflows, and carefully preserve underlying DOM structures with `Array.from(btn.childNodes)` during the loading cycle to avoid rendering regressions.
## 2026-07-20 - 비동기 λ²„νŠΌ λ‘œλ”© μ‹œ aria-busy μƒνƒœ 관리
**Learning:** 비동기 λ™μž‘(예: API μš”μ²­)을 μˆ˜ν–‰ν•˜λŠ” λ²„νŠΌμ΄ `disabled` μƒνƒœλ‘œ 변경될 λ•Œ, μ‹œκ°μ μœΌλ‘œ 'Loading...' ν…μŠ€νŠΈλ₯Ό μ œκ³΅ν•˜λŠ” κ²ƒλ§ŒμœΌλ‘œλŠ” 슀크린 리더 μ‚¬μš©μžμ—κ²Œ λ‘œλ”© μƒνƒœκ°€ λͺ…ν™•ν•˜κ²Œ μ „λ‹¬λ˜μ§€ μ•ŠμŒμ„ ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.
**Action:** λ²„νŠΌμ΄ λ‘œλ”© μƒνƒœμΌ λ•Œ `aria-busy="true"` 속성을 λ™μ μœΌλ‘œ μΆ”κ°€ν•˜κ³ , μž‘μ—…μ΄ μ™„λ£Œλœ ν›„ `.finally()` 블둝을 톡해 μ•ˆμ „ν•˜κ²Œ μ œκ±°ν•˜λŠ” νŒ¨ν„΄μ„ μ μš©ν•˜μ—¬ 접근성을 κ°œμ„ ν•©λ‹ˆλ‹€.
10 changes: 10 additions & 0 deletions src/main/resources/static/assets/viewer/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,12 @@ function renderHistory(history = loadHistory()) {
const btn = e.currentTarget;
const initialChildren = Array.from(btn.childNodes);
btn.disabled = true;
btn.setAttribute("aria-busy", "true");
btn.textContent = "Loading...";
openJobDetail(job).finally(() => {
btn.replaceChildren(...initialChildren);
btn.disabled = false;
btn.removeAttribute("aria-busy");
});
}));
actionsCell.appendChild(createActionButton("Status JSON", () => {
Expand Down Expand Up @@ -299,6 +301,7 @@ async function retryActiveJob() {
const jobId = activeJobDetail.jobId;
const initialChildren = Array.from(el.retryJobBtn.childNodes);
el.retryJobBtn.disabled = true;
el.retryJobBtn.setAttribute("aria-busy", "true");
el.retryJobBtn.textContent = "Retrying...";
setStatus("Requesting operator retry...");

Expand Down Expand Up @@ -340,6 +343,7 @@ async function retryActiveJob() {
} finally {
el.retryJobBtn.replaceChildren(...initialChildren);
el.retryJobBtn.disabled = false;
el.retryJobBtn.removeAttribute("aria-busy");
}
}

Expand Down Expand Up @@ -414,6 +418,7 @@ async function refreshKpis() {
async function refreshKpiEvidence() {
const initialChildren = Array.from(el.refreshEvidenceBtn.childNodes);
el.refreshEvidenceBtn.disabled = true;
el.refreshEvidenceBtn.setAttribute("aria-busy", "true");
el.refreshEvidenceBtn.textContent = "Refreshing...";

try {
Expand All @@ -429,12 +434,14 @@ async function refreshKpiEvidence() {
} finally {
el.refreshEvidenceBtn.replaceChildren(...initialChildren);
el.refreshEvidenceBtn.disabled = false;
el.refreshEvidenceBtn.removeAttribute("aria-busy");
}
}

async function loadDemoData() {
const initialChildren = Array.from(el.loadDemoDataBtn.childNodes);
el.loadDemoDataBtn.disabled = true;
el.loadDemoDataBtn.setAttribute("aria-busy", "true");
el.loadDemoDataBtn.textContent = "Loading...";
setStatus("Loading seeded buyer-demo story...");

Expand All @@ -460,6 +467,7 @@ async function loadDemoData() {
} finally {
el.loadDemoDataBtn.replaceChildren(...initialChildren);
el.loadDemoDataBtn.disabled = false;
el.loadDemoDataBtn.removeAttribute("aria-busy");
}
}

Expand Down Expand Up @@ -507,6 +515,7 @@ async function submitDocument(event) {

const initialChildren = Array.from(el.submitBtn.childNodes);
el.submitBtn.disabled = true;
el.submitBtn.setAttribute("aria-busy", "true");
el.submitBtn.textContent = "Submitting...";
setStatus("Submitting document...");

Expand Down Expand Up @@ -552,6 +561,7 @@ async function submitDocument(event) {
} finally {
el.submitBtn.replaceChildren(...initialChildren);
el.submitBtn.disabled = false;
el.submitBtn.removeAttribute("aria-busy");
}
}

Expand Down
Loading