feat(M02): 좌측 같은 이름 단추 · 나무 뿌리 줄 없앰 · 「+」 더하기 · 찾기 하나(AND) (PLAN 29-6)

- 「일위대가 조합」 · 「구조물 조합」 컨테이너 안 같은 이름 줄 단추 없앰 — 제목을 펼치면 그 화면을 엶
- 나무 맨 위 뿌리 줄 없앰 — 폴더 · 항목부터 · 맨 위 더하기는 빈 자리 오른쪽 클릭 · 층 단추 옆 「+」(읽기만 층 = 숨김) · 빈 나무 안내글 맞춤
- 찾기 칸 하나 — 띄어쓰기 낱말 모두(AND · 대소문자 무시) · 이름 · 키 · 경로(구분 · 상세구분) · 단위 · 공용 matchText 를 나무 · 일위대가 조합 목록이 함께 씀(목록의 따로 찾기 칸 없앰)
- 시험 — 찾기 AND · 새 배치 맞춤

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 18:15:43 +09:00
co-authored by Claude Opus 5.5
parent 95849aefbd
commit c1ad11e869
14 changed files with 127 additions and 51 deletions
@@ -50,5 +50,14 @@ process.stdout.write(
leaf: m.leafName(view.items[0]),
dir: m.folderOf(view.items[0]),
byKey: m.buildFolders(view, "ss000003").items.length + m.buildFolders(view, "SS000003").folders.length,
// 찾기 AND(PLAN 29-6) — 낱말 모두 · 대소문자 무시 · 순서 무관 · 빈 글 = 참
and: [
m.matchText(["돌기슭막이", "메쌓기", "SS000001", "m"], "메쌓기 ss000001"),
m.matchText(["돌기슭막이", "메쌓기", "SS000001", "m"], "ss000001 돌기슭"),
m.matchText(["돌기슭막이", "메쌓기", "SS000001", "m"], "메쌓기 찰쌓기"),
m.matchText(["UC3-000001", "브레인 측구", null, "배수"], ""),
m.matchText(["UC3-000001", "브레인 측구", null, "배수"], "측구 배수"),
],
andTree: m.countItems(m.buildFolders(view, "돌기슭막이 찰쌓기")),
}),
);
+5 -2
View File
@@ -91,11 +91,14 @@ def test_참조표는_열_머리를_못_고침():
def test_나무는_좌측_패널_찾기_칸은_상세_위쪽():
side = _text(M02 / "M02_MasterTemplete_UI_Side.ts")
assert "tree?: HTMLElement[];" in side and "...(opt.tree ?? [])," in side
assert "tree?: HTMLElement[];" in side and "children: opt.tree ?? []" in side
assert 'info.이름 === STRUCTURE_TABLE ? L("M02_KindTable")' in side # 좌측 줄 이름
page = _text(M02 / "M02_MasterTemplete_UI_Page.ts")
assert "createTreePanel({" in page and "tree.select(column)" in page
assert 'tree: [layerBar("구조물조합"), tree.root],' in page and "search: tree.search," in page
assert (
'tree: [layerBar("구조물조합", tree.add), tree.root],' in page
and "search: tree.search," in page
)
main = _text(M02 / "M02_MasterTemplete_UI_Main.ts")
assert 'at.kind === "table" && at.name === STRUCTURE_TABLE && at.layer !== "project"' in main
assert 'isCombo(next) ? L("M02_KindTable")' in main # 상세 제목
+2 -2
View File
@@ -83,8 +83,8 @@ def test_뿌리를_바꿔도_일위대가_화면_유지_해시도_맞춤():
page = (ROOT / "M02_MasterTemplete/M02_MasterTemplete_UI_Page.ts").read_text("utf-8")
assert "go: (next, nextOwner) => void go(next, nextOwner, open)," in page # 두 벌 같은 길
assert (
'bar: layerBar("일위대가"),' in page
and 'tree: [layerBar("구조물조합"), tree.root],' in page
'bar: (add) => layerBar("일위대가", add),' in page
and 'tree: [layerBar("구조물조합", tree.add), tree.root],' in page
)
labor = page.split("buildLaborSection({")[1].split("make:")[0]
assert 'mark("일위대가")' in labor # 여는 순간 해시 open
@@ -122,7 +122,8 @@ def test_좌측_줄은_구조물_집계_양식_아래_한_줄_같은_한_곳에
)
# 차례 = 일위대가 조합(27-2b) → 구조물 조합 → 옵션 → 도면 양식
order = [
"...(labor ? [section(labor.title, labor.body)] : []),",
"...(labor ? [openOnExpand(section(labor.title, labor.body), () => void labor.open())]"
" : []),",
" summary,",
" ...(extras ? [extras.옵션, extras.도면] : []),",
]
+8 -1
View File
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
"""M02 관리 화면 구조물 라이브러리(PLAN 26-3a) 자료 셈 회귀검증 — 폴더 나무 · 빈 폴더 · 깊이 5 · 찾기 · 폴더 목록.
"""M02 구조물 라이브러리(PLAN 26-3a) 자료 셈 회귀검증 — 폴더 나무 · 빈 폴더 · 깊이 5 · 찾기 ·
폴더 목록.
항목 경로 = 폴더 이름 배열 + 마지막 마디가 항목 이름 · 찾는 글이 있으면 맞는 항목과 위 폴더만.
Node 헬퍼(`helper_m02_treepanel.cjs`)가 TS 를 트랜스파일해 돌리고, 여기서 값을 판정한다.
@@ -58,6 +59,12 @@ def test_키로도_찾음(results):
assert results["byKey"] == 1
def test_찾기는_낱말_모두_AND(results):
"""PLAN 29-6 — 띄어쓰기로 나눈 낱말을 모두 담은 것만 · 대소문자 무시 · 빈 글 = 전부."""
assert results["and"] == [True, True, False, True, True]
assert results["andTree"] == 1 # 「돌기슭막이 찰쌓기」 = c2 하나
def test_폴더_목록과_위_길(results):
assert ["다섯", "둘", "셋", "넷"] in results["folders"]
assert ["빈 폴더"] in results["folders"]