fix(cafe24): 옵션 모달 — 옵션 열 축소·품목 표 확대, 창 바닥까지 사용, 품목코드 복사
- 옵션 정의 열 400 → 340px, 모달 폭 1180 → 1280px. 품목 표 열 폭을 줄여
옵션값 이름이 한 줄(넘치면 말줄임 + title)에 들어가게.
- 모달 높이를 90vh 고정으로 바꾸고 두 열이 바닥까지 늘어나 각자 스크롤
(품목은 표만 스크롤, 저장 버튼 고정). 첫 구현 때 남은 옛 규칙
`.cf24-variants-wrap { max-height: 320px }` 가 표 높이를 막고 있었다
(헤드리스 크롬 실측으로 발견) — 제거.
- 품목코드 클릭 = 클립보드 복사("복사됨" 표시, 비보안 컨텍스트는 execCommand).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{% extends "erp_base.html" %}
|
||||
|
||||
{% block head_extra %}
|
||||
<link rel="stylesheet" href="/static/cafe24.css?v=20260918c" />
|
||||
<link rel="stylesheet" href="/static/cafe24.css?v=20260918d" />
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
@@ -1007,7 +1007,7 @@
|
||||
}
|
||||
|
||||
// 옵션 정의 편집 (모달 왼쪽 열)
|
||||
var html = '<div class="cf24-modal-grid"><section class="cf24-modal-col">' +
|
||||
var html = '<div class="cf24-modal-grid"><section class="cf24-modal-col cf24-modal-col-options">' +
|
||||
'<h4 class="cf24-side-title">옵션 정의</h4>' +
|
||||
'<form class="cf24-side-form" id="cf24-opt-form">';
|
||||
opt.options.forEach(function (o, gi) {
|
||||
@@ -1041,7 +1041,7 @@
|
||||
"</section>";
|
||||
|
||||
// 품목 표 (모달 오른쪽 열) — 넓은 창이라 한 줄에 다 들어간다.
|
||||
html += '<section class="cf24-modal-col"><h4 class="cf24-side-title">품목 (' + variants.length + ')</h4>';
|
||||
html += '<section class="cf24-modal-col cf24-modal-col-variants"><h4 class="cf24-side-title">품목 (' + variants.length + ')</h4>';
|
||||
if (!variants.length) {
|
||||
html += '<p class="cf24-muted">품목이 아직 조회되지 않았습니다. 잠시 뒤 창을 닫았다 다시 여세요.</p>';
|
||||
} else {
|
||||
@@ -1054,8 +1054,8 @@
|
||||
var amount = String(parseInt(v.additional_amount || "0", 10) || 0);
|
||||
html += '<tr class="cf24-v-item" data-code="' + escHtml(v.variant_code) + '">' +
|
||||
'<td class="cf24-v-imgcol">' + (v.image ? '<img class="cf24-v-img" src="' + escHtml(v.image) + '" alt="" />' : '<span class="cf24-v-img cf24-v-img-empty"></span>') + "</td>" +
|
||||
'<td class="cf24-v-name">' + escHtml(label) + "</td>" +
|
||||
'<td class="cf24-v-syscode"><code>' + escHtml(v.variant_code) + "</code></td>" +
|
||||
'<td class="cf24-v-name" title="' + escHtml(label) + '">' + escHtml(label) + "</td>" +
|
||||
'<td class="cf24-v-syscode"><button type="button" class="cf24-v-copy" data-copy-text="' + escHtml(v.variant_code) + '" title="클릭하면 품목코드를 복사합니다">' + escHtml(v.variant_code) + "</button></td>" +
|
||||
'<td class="cf24-v-code"><input type="text" name="custom_variant_code" maxlength="40" value="' + escHtml(v.custom_variant_code) + '" /></td>' +
|
||||
'<td class="cf24-v-amount"><input type="text" name="additional_amount" inputmode="numeric" value="' + escHtml(amount) + '" /></td>' +
|
||||
'<td class="cf24-v-flag"><button type="button" class="cf24-v-toggle' + (v.display ? " is-on" : "") + '" data-flag="display" data-on="' + (v.display ? 1 : 0) + '" data-initial="' + (v.display ? 1 : 0) + '">' + (v.display ? "진열" : "미진열") + "</button></td>" +
|
||||
@@ -1147,6 +1147,34 @@
|
||||
if (!saveBtn) return;
|
||||
var wrap = body.querySelector(".cf24-variants-wrap");
|
||||
trackDirty(wrap);
|
||||
// 품목코드 클릭 = 클립보드 복사 (HTTPS 가 아니면 execCommand 로 대체)
|
||||
wrap.querySelectorAll(".cf24-v-copy").forEach(function (btn) {
|
||||
btn.addEventListener("click", function () {
|
||||
var text = btn.dataset.copyText || btn.textContent;
|
||||
var done = function () {
|
||||
var old = btn.textContent;
|
||||
btn.textContent = "복사됨";
|
||||
btn.classList.add("is-copied");
|
||||
setTimeout(function () { btn.textContent = old; btn.classList.remove("is-copied"); }, 1200);
|
||||
};
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
navigator.clipboard.writeText(text).then(done, function () { fallbackCopy(text, done); });
|
||||
} else {
|
||||
fallbackCopy(text, done);
|
||||
}
|
||||
});
|
||||
});
|
||||
function fallbackCopy(text, done) {
|
||||
var ta = document.createElement("textarea");
|
||||
ta.value = text;
|
||||
ta.setAttribute("readonly", "");
|
||||
ta.style.position = "fixed";
|
||||
ta.style.opacity = "0";
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
try { if (document.execCommand("copy")) done(); } catch (e) { /* 복사 불가 — 조용히 무시 */ }
|
||||
document.body.removeChild(ta);
|
||||
}
|
||||
wrap.querySelectorAll(".cf24-v-toggle").forEach(function (btn) {
|
||||
btn.addEventListener("click", function () {
|
||||
var on = btn.dataset.on !== "1";
|
||||
|
||||
+62
-22
@@ -1130,8 +1130,10 @@ body.cf24-modal-open {
|
||||
.cf24-modal-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: min(1180px, 96vw);
|
||||
max-height: 90vh;
|
||||
width: min(1280px, 96vw);
|
||||
/* max-height 가 아니라 height 고정 — 두 열이 창 바닥까지 늘어나고 각 열 안에서
|
||||
스크롤한다(품목이 많을 때 표만 스크롤, 저장 버튼은 항상 보임). */
|
||||
height: 90vh;
|
||||
background: var(--color-canvas-white, #fff);
|
||||
border-radius: var(--r-xl, 14px);
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
||||
@@ -1176,27 +1178,52 @@ body.cf24-modal-open {
|
||||
}
|
||||
|
||||
.cf24-modal-body {
|
||||
padding: 16px 18px 20px;
|
||||
overflow: auto;
|
||||
padding: 16px 18px 18px;
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 옵션 정의(왼쪽, 좁게) | 품목 표(오른쪽, 남는 폭 전부). 두 열 모두 창 바닥까지. */
|
||||
.cf24-modal-grid {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
display: grid;
|
||||
grid-template-columns: 400px minmax(0, 1fr);
|
||||
grid-template-columns: 340px minmax(0, 1fr);
|
||||
grid-template-rows: minmax(0, 1fr);
|
||||
gap: 24px;
|
||||
align-items: start;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
@media (max-width: 960px) {
|
||||
.cf24-modal-grid {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
grid-template-rows: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.cf24-modal-col {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 왼쪽 열은 통째로 스크롤, 오른쪽 열은 표만 스크롤(제목·저장 버튼 고정) */
|
||||
.cf24-modal-col-options {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.cf24-modal-col-variants > .cf24-variants-wrap {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
border-bottom: 1px solid var(--color-subtle-ash, #e5e5e5);
|
||||
}
|
||||
|
||||
.cf24-modal-col-variants > .cf24-side-actions {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
/* 옵션이 없는 상품의 생성 폼 — 넓은 모달에서 끝까지 늘어나지 않게 */
|
||||
@@ -1229,18 +1256,37 @@ body.cf24-modal-open {
|
||||
background: var(--color-canvas-white, #fff);
|
||||
}
|
||||
|
||||
.cf24-variants-wrap {
|
||||
max-height: 62vh;
|
||||
overflow: auto;
|
||||
/* 열 폭 — 옵션 이름이 한 줄에 들어가도록 나머지를 좁게 잡는다
|
||||
(1280px 모달: 340 옵션 + 24 간격 → 표 약 880px, 이름 칸 약 420px). */
|
||||
.cf24-v-imgcol { width: 40px; }
|
||||
.cf24-v-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 0; }
|
||||
.cf24-v-syscode { width: 104px; }
|
||||
.cf24-v-code { width: 132px; }
|
||||
.cf24-v-amount { width: 90px; }
|
||||
.cf24-v-amount input { text-align: right; }
|
||||
.cf24-v-flag { width: 56px; text-align: center; }
|
||||
|
||||
/* 품목코드 — 클릭하면 클립보드로. 눌리는 것임을 커서·밑줄로 알린다. */
|
||||
.cf24-v-copy {
|
||||
font-family: var(--font-geist-mono, ui-monospace, monospace);
|
||||
font-size: 11px;
|
||||
color: var(--color-midtone-gray, #737373);
|
||||
background: transparent;
|
||||
border: 0;
|
||||
padding: 2px 4px;
|
||||
border-radius: var(--r-sm, 4px);
|
||||
cursor: copy;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.cf24-v-imgcol { width: 40px; }
|
||||
.cf24-v-syscode { width: 110px; }
|
||||
.cf24-v-syscode code { font-size: 11px; color: var(--color-midtone-gray, #737373); }
|
||||
.cf24-v-code { width: 150px; }
|
||||
.cf24-v-amount { width: 96px; }
|
||||
.cf24-v-amount input { text-align: right; }
|
||||
.cf24-v-flag { width: 58px; text-align: center; }
|
||||
.cf24-v-copy:hover {
|
||||
background: var(--color-ghost-gray, #f2f2f2);
|
||||
color: var(--color-rich-black, #0a0a0a);
|
||||
}
|
||||
|
||||
.cf24-v-copy.is-copied {
|
||||
color: var(--color-success-green, #10c22b);
|
||||
}
|
||||
|
||||
.cf24-v-img {
|
||||
width: 32px;
|
||||
@@ -1258,7 +1304,6 @@ body.cf24-modal-open {
|
||||
|
||||
.cf24-v-name {
|
||||
font-weight: 500;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.cf24-variants input[type="text"] {
|
||||
@@ -1292,11 +1337,6 @@ body.cf24-modal-open {
|
||||
box-shadow: 0 0 0 2px #f0b429;
|
||||
}
|
||||
|
||||
.cf24-variants-wrap {
|
||||
max-height: 320px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.cf24-opt-danger {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
Reference in New Issue
Block a user