Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
@@ -1,3 +1,6 @@
## 2024-08-14 - 드롭 존 클릭 영역 활성화 시의 상호작용 제어 학습
**Learning:** 파일 업로드 폼을 감싸는 전체 드롭 존(box)을 클릭 가능하도록 확장할 때, 폼 내부의 INPUT, BUTTON, LABEL 등 원래의 상호작용 가능한 하위 요소에 대한 클릭까지 모두 부모 래퍼의 이벤트로 처리하면 의도치 않은 중복 동작이나 UI 오작동이 발생함을 확인.
**Action:** 상호작용하는 드롭 존 이벤트를 추가할 시, `!['INPUT', 'BUTTON', 'LABEL'].includes(e.target.tagName)` 와 같은 명시적인 예외 처리를 도입하여 원래의 폼 기능을 해치지 않고 UX를 개선한다.
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
## 2024-07-15 - Dynamic Size formatting and Total Size Validation
**Learning:** Hardcoding human-readable sizes (like '5 GiB') in validation error messages is error-prone when the underlying constant changes. Moreover, failing to validate total upload size against backend limits (e.g., MAX_UPLOAD_BYTES) in batch file uploads frustrates users who wait for a large upload to finish only to get a server-side 413 Payload Too Large error.
**Action:** Always format backend byte limit constants dynamically (e.g., `formatBinaryBytes(MAX_UPLOAD_BYTES)`) on the client side to display accurate error messages. For multiple file inputs, ensure both the file count and the combined file size are validated against backend limits, giving immediate inline feedback via `setCustomValidity` and `aria-invalid`.
Expand Down
14 changes: 13 additions & 1 deletion saas_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ async def add_security_headers(request: Request, call_next):
<title>Codec Carver SaaS</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 40px auto; padding: 20px; }
.box { border: 1px solid #ccc; padding: 20px; border-radius: 8px; }
.box { border: 1px solid #ccc; padding: 20px; border-radius: 8px; cursor: pointer; }
button { padding: 10px 20px; background-color: #0056b3; color: white; border: none; border-radius: 4px; cursor: pointer; }
button:hover:not(:disabled) { background-color: #004085; }
button:disabled { background-color: #6c757d; cursor: not-allowed; }
Expand Down Expand Up @@ -403,6 +403,18 @@ async def add_security_headers(request: Request, call_next):
}
}, false);
}
dropZone.addEventListener('click', (e) => {
if (!['INPUT', 'BUTTON', 'LABEL'].includes(e.target.tagName)) {
fileInput.click();
}
});
if (batchDropZone) {
batchDropZone.addEventListener('click', (e) => {
if (!['INPUT', 'BUTTON', 'LABEL'].includes(e.target.tagName)) {
batchFileInput.click();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
});
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
</script>
</div>
<div class="box" id="batch-drop-zone" style="margin-top: 20px;">
Expand Down
3 changes: 3 additions & 0 deletions tests/test_saas_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ def test_get_ui_includes_accessible_file_input_helpers(self):
self.assertIn('id="file_help"', html)
self.assertIn('class="required-star" aria-hidden="true"', html)

self.assertIn("['INPUT', 'BUTTON', 'LABEL'].includes(e.target.tagName)", html)
self.assertIn("fileInput.click();", html)

def test_get_ui_includes_binary_file_size_validation(self):
response = client.get("/")
self.assertEqual(response.status_code, 200)
Expand Down
Loading