diff --git a/app/modules/expense/templates/expense/index.html b/app/modules/expense/templates/expense/index.html index 2c759b7..18ce68a 100644 --- a/app/modules/expense/templates/expense/index.html +++ b/app/modules/expense/templates/expense/index.html @@ -84,24 +84,18 @@ - - - + + {% for it in items %} - @@ -127,6 +121,14 @@ {% endif %} {% if supports_workflow %} - - + {% endif %} {% else %} - + {% endfor %}
사용일 분류 수단 가맹점 금액상태동작상태동작
- {% if supports_workflow %} - - {% endif %} - {{ it.spent_at }} {{ it.category }} {{ it.method }} + {% if it.status in ('작성중', '반려') and supports_workflow %} + + + {% endif %} {% if it.status in ('작성중', '반려') %} @@ -139,24 +141,9 @@
-
- 첨부파일 - {% if it.status in ('작성중', '반려') %} -
- - -
- {% endif %} -
  • 불러오는 중…
@@ -170,7 +157,7 @@
등록된 경비가 없습니다.
등록된 경비가 없습니다.
@@ -183,16 +170,10 @@ .erp-page-actions { display: flex; gap: var(--sp-8); margin-bottom: var(--sp-16); flex-wrap: wrap; } - .ex-detail-box { - background: var(--color-ghost-gray); - padding: var(--sp-12) var(--sp-16); - border-radius: 8px; - } - .ex-attach-head { - display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); - margin-bottom: 8px; - } - .ex-upload { display: flex; gap: 6px; } + /* detail 행은 메인 행 바로 아래 — 위쪽 보더만 살짝, 좌측 들여쓰기 */ + tr.ex-detail > td { padding: 6px var(--sp-16) var(--sp-12) 110px; background: var(--color-canvas-white); } + tr.ex-detail + tr[data-id] > td { border-top: 1px solid var(--color-subtle-ash); } + .ex-detail-box { background: transparent; padding: 0; } .ex-attach-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; } .ex-attach-list li { display: flex; align-items: center; gap: 8px; padding: 6px 8px; @@ -310,23 +291,13 @@ tbody.addEventListener("click", async (e) => { const btn = e.target.closest("button"); if (!btn) return; - const tr = btn.closest("tr[data-id]"); - if (!tr) return; - const id = tr.dataset.id; + // 메인 행 또는 detail 행 모두 처리 + const mainTr = btn.closest("tr[data-id]"); + const detailTr = btn.closest("tr.ex-detail"); + const id = mainTr ? mainTr.dataset.id : (detailTr ? detailTr.dataset.detailFor : null); + if (!id) return; - if (btn.classList.contains("js-toggle")) { - const detail = tbody.querySelector(`tr.ex-detail[data-detail-for="${id}"]`); - if (!detail) return; - const opening = detail.hasAttribute("hidden"); - if (opening) { - detail.removeAttribute("hidden"); - btn.textContent = "▾"; - loadAttachments(id); - } else { - detail.setAttribute("hidden", ""); - btn.textContent = "▸"; - } - } else if (btn.classList.contains("js-edit")) { + if (btn.classList.contains("js-edit")) { const res = await fetch(`/expense/api/items`); if (!res.ok) return; const { items } = await res.json(); @@ -353,13 +324,13 @@ } }); - // 첨부 업로드 + // 첨부 업로드 (메인 행 동작셀 input) tbody.addEventListener("change", async (e) => { const input = e.target.closest("input.js-upload"); if (!input || !input.files.length) return; - const tr = input.closest("tr.ex-detail"); - if (!tr) return; - const itemId = tr.dataset.detailFor; + const mainTr = input.closest("tr[data-id]"); + if (!mainTr) return; + const itemId = mainTr.dataset.id; const fd = new FormData(); fd.append("file", input.files[0]); fd.append("kind", input.dataset.kind || "other"); @@ -375,6 +346,13 @@ } }); + // 페이지 로드 시 모든 detail 행의 첨부 자동 로드 + if (supportsWorkflow) { + tbody.querySelectorAll("tr.ex-detail[data-detail-for]").forEach((tr) => { + loadAttachments(tr.dataset.detailFor); + }); + } + if (!form.spent_at.value) { const d = new Date(); form.spent_at.value = `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}-${String(d.getDate()).padStart(2,"0")}`;