130 lines
5.6 KiB
Python
130 lines
5.6 KiB
Python
"""243-1 · 126 — B08 · B09 값 고칠 수 있는 표 전부 더블클릭 입력 · 고칠 칸 테두리 = 246-1 에서 지움.
|
|
|
|
- 공용 표 editOnDouble = 한 번 누름 = 글 상자 안 열림 · 더블클릭 · 칸 누른 뒤 Enter · F2 = 그 칸 글 상자
|
|
- 고칠 수 있는 칸(td) 표시 `is-can-edit` 없음(246-1 · 241 앞 모양)
|
|
- B09 = 표 만드는 길 한 곳(Shell) · B08 = 고칠 칸 있는 표(자재 집계표 셋) 모두 editOnDouble
|
|
- 칸 누름으로 여는 메뉴 · 고르기 · 이동(onCellClick · choices · link)은 그대로
|
|
"""
|
|
|
|
import json
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
from test_184_3_b09_bill_menu import _node # noqa: E402
|
|
from test_235_1_b09_bill_tree import DOM_JS, TABLE # noqa: E402
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
HARNESS = DOM_JS.split("const columns")[0]
|
|
|
|
SCENE_JS = """
|
|
const columns = [{ key: "name", label: "명칭" }, { key: "qty", label: "수량", kind: "number" }];
|
|
const rows = [{ name: "폴더", qty: null }, { name: "파일", qty: 3 }];
|
|
const can = (html) => [...html.matchAll(/<td class="([^"]*)"[^>]*>([^<]*)</g)]
|
|
.filter((m) => m[1].includes("is-can-edit")).map((m) => m[2]);
|
|
const log = [];
|
|
const make = (extra = {}) => createDataTable({ columns, rows, editOnDouble: true,
|
|
editable: (i, k) => i === 1 && k === "qty", onCellClick: (i, k) => log.push(`click ${i}:${k}`),
|
|
onEdit: (i, k, v) => log.push(`edit ${i}:${k}=${v}`), ...extra });
|
|
const key = (r, k, target, more = {}) => r.fire("keydown", { key: k, target, isComposing: false, ...more,
|
|
preventDefault() {}, stopPropagation() {} });
|
|
const out = {};
|
|
const t = make();
|
|
const r = t.root;
|
|
out.can = can(r.html);
|
|
out.start = inputs(r);
|
|
r.fire("click", { target: target(r, 1, 1) });
|
|
out.click = [inputs(r), [...log]];
|
|
key(r, "F2", r);
|
|
out.f2 = inputs(r);
|
|
const typed = doc.activeElement;
|
|
doc.activeElement = r; // 초점 떠남
|
|
r.fire("change", { target: typed });
|
|
r.fire("focusout", { target: typed });
|
|
const enter = () => {
|
|
r.fire("click", { target: target(r, 1, 1) });
|
|
key(r, "Enter", r);
|
|
};
|
|
setTimeout(() => {
|
|
out.afterEnd = inputs(r);
|
|
enter();
|
|
out.enter = inputs(r);
|
|
const input = doc.activeElement;
|
|
key(r, "Enter", input, { isComposing: true });
|
|
out.composing = doc.activeElement === input;
|
|
key(r, "Enter", input);
|
|
out.ends = doc.activeElement === r;
|
|
r.fire("focusout", { target: input });
|
|
setTimeout(() => {
|
|
r.fire("click", { target: target(r, 0, 0) });
|
|
key(r, "F2", r);
|
|
out.noEditCell = inputs(r);
|
|
const off = make({ keyEdit: false });
|
|
off.root.fire("click", { target: target(off.root, 1, 1) });
|
|
key(off.root, "F2", off.root);
|
|
out.keyEditOff = inputs(off.root);
|
|
off.root.fire("dblclick", { target: target(off.root, 1, 1) });
|
|
out.keyEditOffDbl = inputs(off.root);
|
|
const old = createDataTable({ columns, rows, editable: (i, k) => i === 1 && k === "qty" });
|
|
out.old = [inputs(old.root), can(old.root.html)];
|
|
console.log(JSON.stringify(out));
|
|
}, 5);
|
|
}, 5);
|
|
"""
|
|
|
|
|
|
def test_공용_표_더블클릭_Enter_F2():
|
|
out = json.loads(_node(TABLE + HARNESS + SCENE_JS))
|
|
assert out["can"] == [] # 246-1 고칠 칸 td 표시 없음
|
|
assert out["start"] == [] # 처음 = 글 상자 없음
|
|
assert out["click"] == [[], ["click 1:qty"]] # 한 번 누름 = 안 열림 · 누름 알림은 그대로
|
|
assert out["f2"] == ["1:qty"] # F2 = 누른 칸 입력
|
|
assert out["afterEnd"] == [] # 초점 떠남 = 끝
|
|
assert out["enter"] == ["1:qty"] # Enter = 누른 칸 입력
|
|
assert out["composing"] is True # 한글 조합 중 Enter = 조합 끝(입력 유지)
|
|
assert out["ends"] is True # 조합 뒤 Enter = 입력 끝
|
|
assert out["noEditCell"] == [] # 못 고치는 칸 = 안 열림
|
|
assert out["keyEditOff"] == [] # keyEdit false = 표가 키를 안 받음
|
|
assert out["keyEditOffDbl"] == ["1:qty"] # 더블클릭은 그대로
|
|
assert out["old"] == [["1:qty"], []] # editOnDouble 없는 표 = 예전대로(테두리 class 없음)
|
|
|
|
|
|
def test_고칠_칸_테두리_CSS_없음():
|
|
css = (ROOT / "ui_template" / "ui_template_data_table.css").read_text("utf-8")
|
|
ts = (ROOT / "ui_template" / "ui_template_data_table.ts").read_text("utf-8")
|
|
assert "is-can-edit" not in css and "is-can-edit" not in ts # 246-1 되돌림
|
|
|
|
|
|
def _sources(*folders: str) -> list[Path]:
|
|
return [p for f in folders for p in sorted((ROOT / f).glob("*.ts"))]
|
|
|
|
|
|
def test_B09_표_만드는_길_한_곳_더블클릭_기본():
|
|
calls = [
|
|
p.name for p in _sources("B09_Estimation") if "createDataTable({" in p.read_text("utf-8")
|
|
]
|
|
assert calls == ["B09_Estimation_UI_Shell.ts"]
|
|
shell = (ROOT / "B09_Estimation" / calls[0]).read_text("utf-8")
|
|
assert "editOnDouble: spec.editOnDouble ?? true," in shell
|
|
assert "keyEdit: !(spec as BillTable).menu," in shell # 설계내역서 Enter · F2 = 레벨 키 몫
|
|
|
|
|
|
def test_B08_고칠_칸_있는_표_모두_editOnDouble():
|
|
seen = 0
|
|
for p in _sources("B08_Quantity"):
|
|
text = p.read_text("utf-8")
|
|
for call in re.split(r"createDataTable\(\{", text)[1:]:
|
|
block = call.split("\n });")[0]
|
|
if "editable:" in block:
|
|
seen += 1
|
|
assert "editOnDouble: true" in block, p.name
|
|
# 자재 집계표 셋이 한 표 만드는 길(Material)을 같이 씀 + 거리이정표 표(구간 · 표 줄 표는 244-4 에서 모달로)
|
|
assert seen == 2
|
|
|
|
|
|
def test_고르기_메뉴_이동_그대로():
|
|
shell = (ROOT / "B09_Estimation" / "B09_Estimation_UI_Shell.ts").read_text("utf-8")
|
|
assert "if (spec.link && !spec.editable?.(i, key)) goto(spec.link(i, key));" in shell
|
|
assert "spec.choices?.(Number(cell.parentElement?.dataset.i), column.key)" in shell
|