feat(M02): 일위대가 「새 조합」 단추를 제목 줄 오른쪽 끝으로 · 조합 목록 공용 표 모양(PLAN 30-5 일위대가)
- UI_Main showView 에 tools(빈 slot · 다음 열기 때 drop 이 비움) · .m02-main__tools 오른쪽 끝 - 읽기 층은 단추 없음 · 목록 안 옛 단추 뺌 - 조합 목록 = ui-general-block__table(줄 선 · 머리 줄 고정) · 줄 누름 모양 - 시험 test_m02_labor_tree 한 건 더함 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BU9gbNE3aWFUvE61pS2WGt
This commit is contained in:
@@ -12,3 +12,12 @@
|
||||
.m01-combo .m01-logic__muted {
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
/* 조합 목록 — 공용 표 모양(줄 선 · 머리 줄) · 줄을 누르면 상세(PLAN 30-5) */
|
||||
.m02-labor__list tbody tr {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.m02-labor__list tbody tr:hover {
|
||||
background: var(--color-mist-violet);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ export interface LaborLibrary {
|
||||
/** 켜진 층 단추를 다시 누름 — 조합 목록으로(저장 안 한 고침은 물음 · PLAN 30-4) */
|
||||
back: () => Promise<void>;
|
||||
refresh: () => Promise<void>;
|
||||
/** 제목 줄 오른쪽 끝 도구 — 「새 조합」(읽기 층 = null · PLAN 30-5) */
|
||||
tools: HTMLElement | null;
|
||||
/** 메인 칸 「저장 안 한 고침」 손잡이 */
|
||||
bind: (setDirty: (dirty: boolean) => void) => void;
|
||||
}
|
||||
@@ -157,13 +159,14 @@ export function buildLaborLibrary(opt: LaborLibraryOptions): LaborLibrary {
|
||||
editor.showList();
|
||||
},
|
||||
refresh: () => tree.refresh(),
|
||||
tools: editor.newButton,
|
||||
bind: (fn) => (setDirty = fn),
|
||||
};
|
||||
}
|
||||
|
||||
export interface LaborSectionOptions {
|
||||
/** 메인 칸에 화면을 띄움 — 고침 표시 손잡이를 돌려받음 */
|
||||
show: (label: string, node: HTMLElement) => (dirty: boolean) => void;
|
||||
show: (label: string, node: HTMLElement, tools?: HTMLElement | null) => (dirty: boolean) => void;
|
||||
/** 저장 안 한 고침을 버릴지 확인 — 취소면 false */
|
||||
confirmLeave: () => Promise<boolean>;
|
||||
/** 화면을 열었음 — 좌측 다른 고름 표시를 지움 */
|
||||
@@ -193,7 +196,7 @@ export function buildLaborSection(opt: LaborSectionOptions): LaborSection {
|
||||
|
||||
async function open(): Promise<void> {
|
||||
if (opened || !(await opt.confirmLeave())) return;
|
||||
library.bind(opt.show(tc("Library"), library.root));
|
||||
library.bind(opt.show(tc("Library"), library.root, library.tools));
|
||||
opt.onOpen();
|
||||
mark(true);
|
||||
await library.refresh();
|
||||
|
||||
@@ -29,6 +29,7 @@ import { tc } from "./M02_MasterTemplete_Labor_Text";
|
||||
import { matchText } from "./M02_MasterTemplete_TreePanel_Model";
|
||||
import "../M01_MasterData/M01_MasterData_UI_Logic_Style.css";
|
||||
import "../M01_MasterData/M01_MasterData_UI_LogicLab_Style.css";
|
||||
import "@ui/ui_template_general_layout.css";
|
||||
import "./M02_MasterTemplete_Labor.css";
|
||||
|
||||
const blankCombo = (path: string[] = []): Combo => ({
|
||||
@@ -75,6 +76,8 @@ export interface LaborEditor {
|
||||
/** 나무 「조합 더하기」 — 그 폴더(구분 · 상세구분)를 채운 빈 조합 */
|
||||
startNew: (path: string[]) => void;
|
||||
showList: () => void;
|
||||
/** 「새 조합」 — 제목 줄 오른쪽 끝에 붙임(읽기 층 = null) */
|
||||
newButton: HTMLElement | null;
|
||||
isDirty: () => boolean;
|
||||
/** 열린 조합 키 — 목록이면 null · 새 조합이면 빈 글 */
|
||||
current: () => string | null;
|
||||
@@ -141,21 +144,15 @@ export function createLaborEditor(opt: LaborEditOptions): LaborEditor {
|
||||
tr.addEventListener("click", () => void open(x.키));
|
||||
return tr;
|
||||
});
|
||||
// 「새 조합」은 제목 줄 오른쪽 끝(`newButton` · PLAN 30-5) · 목록 = 공용 표 모양(줄 선 · 머리 줄)
|
||||
view.replaceChildren(
|
||||
el("div", {
|
||||
className: "m01-logic__section-head",
|
||||
children: [
|
||||
...(edit
|
||||
? [createButton({ label: tc("New"), variant: "filled", onClick: () => startNew([]) })]
|
||||
: [el("span", { className: "m01-logic__muted", text: tc("ReadOnly") })]),
|
||||
],
|
||||
}),
|
||||
...(edit ? [] : [el("p", { className: "m01-logic__muted", text: tc("ReadOnly") })]),
|
||||
shown.length
|
||||
? el("div", {
|
||||
className: "m01-master__grid-wrap",
|
||||
className: "ui-general-block__table-wrap ui-general-block__table-wrap--sticky-head",
|
||||
children: [
|
||||
el("table", {
|
||||
className: "m01-master__grid",
|
||||
className: "ui-general-block__table m02-labor__list",
|
||||
children: [
|
||||
el("thead", {
|
||||
children: [el("tr", { children: heads.map((t) => el("th", { text: t })) })],
|
||||
@@ -387,6 +384,9 @@ export function createLaborEditor(opt: LaborEditOptions): LaborEditor {
|
||||
open,
|
||||
startNew,
|
||||
showList: drawList,
|
||||
newButton: edit
|
||||
? createButton({ label: tc("New"), variant: "filled", onClick: () => startNew([]) })
|
||||
: null,
|
||||
isDirty: dirty,
|
||||
current: () => current?.combo.키 ?? null,
|
||||
setQuery,
|
||||
|
||||
@@ -93,7 +93,11 @@ export interface MainHandle {
|
||||
/** 저장 안 한 고침이 있으면 버릴지 물음 — 취소면 false */
|
||||
confirmLeave: () => Promise<boolean>;
|
||||
/** 양식 밖 화면(좌측 자재 조합 상세)을 띄움 — 머리는 제목만 · 고침 표시 손잡이를 돌려줌 */
|
||||
showView: (label: string, node: HTMLElement) => (dirty: boolean) => void;
|
||||
showView: (
|
||||
label: string,
|
||||
node: HTMLElement,
|
||||
tools?: HTMLElement | null,
|
||||
) => (dirty: boolean) => void;
|
||||
/** 구조물집계표를 열고 그 열을 고름 — 이미 표면 다시 안 읽음(`fresh` 면 다시 읽음) */
|
||||
openTable: (layer: Layer, colId?: string | null, fresh?: boolean) => Promise<void>;
|
||||
/** 나무를 고치기 전 — 저장 안 한 고침이 있으면 저장 · 버림 · 취소를 물음 */
|
||||
@@ -512,7 +516,12 @@ export function createMain(
|
||||
}
|
||||
}
|
||||
|
||||
function showView(label: string, node: HTMLElement): (d: boolean) => void {
|
||||
/** `tools` = 제목 줄 오른쪽 끝(빈 slot 에 · 다음에 열 때 `drop` 이 비움 · 일위대가 「새 조합」) */
|
||||
function showView(
|
||||
label: string,
|
||||
node: HTMLElement,
|
||||
tools?: HTMLElement | null,
|
||||
): (d: boolean) => void {
|
||||
++seq;
|
||||
dirty = false;
|
||||
drop();
|
||||
@@ -523,6 +532,8 @@ export function createMain(
|
||||
showAside();
|
||||
title.textContent = label;
|
||||
host.replaceChildren(node);
|
||||
if (tools)
|
||||
slot.replaceChildren(el("span", { className: "m02-main__tools", children: [tools] }));
|
||||
return (d) => (dirty = d);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,12 @@
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* 제목 줄 오른쪽 끝 도구(일위대가 「새 조합」 · PLAN 30-5) */
|
||||
.m02-main__tools {
|
||||
display: inline-flex;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.m02-main__notice {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -226,4 +232,4 @@
|
||||
|
||||
.m02-main__head + .m02-tree__search {
|
||||
margin-bottom: var(--spacing-8);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,3 +101,24 @@ def test_일위대가_나무에_여러_개_복사_붙여넣기_연결():
|
||||
assert "pasteCombos(clip.from as LaborScope, pick, dest, list.판, to)" in labor # 대상 층
|
||||
page = (ROOT / "M02_MasterTemplete/M02_MasterTemplete_UI_Page.ts").read_text("utf-8")
|
||||
assert "canEdit: isAdmin, reveal, copyTo })" in page # 구조물 나무와 같은 「〇〇로 복사」 목록
|
||||
|
||||
|
||||
def test_새_조합_단추는_제목_줄_오른쪽_목록은_공용_표():
|
||||
"""PLAN 30-5 — 「새 조합」 = 제목 줄 오른쪽 끝(읽기 층 없음) · 목록 = 공용 표(줄 선).
|
||||
머리 줄도 공용 표 모양."""
|
||||
edit = (ROOT / "M02_MasterTemplete/M02_MasterTemplete_Labor_Edit.ts").read_text("utf-8")
|
||||
assert (
|
||||
"newButton: edit" in edit and 'className: "ui-general-block__table m02-labor__list"' in edit
|
||||
)
|
||||
assert (
|
||||
'tc("New"), variant: "filled", onClick: () => startNew([]) })]' not in edit
|
||||
) # 목록 안 옛 자리
|
||||
labor = (ROOT / "M02_MasterTemplete/M02_MasterTemplete_Labor.ts").read_text("utf-8")
|
||||
assert 'library.bind(opt.show(tc("Library"), library.root, library.tools))' in labor
|
||||
main = (ROOT / "M02_MasterTemplete/M02_MasterTemplete_UI_Main.ts").read_text("utf-8")
|
||||
assert (
|
||||
'slot.replaceChildren(el("span", { className: "m02-main__tools", children: [tools] }))'
|
||||
in main
|
||||
)
|
||||
css = (ROOT / "M02_MasterTemplete/M02_MasterTemplete_UI_Style.css").read_text("utf-8")
|
||||
assert ".m02-main__tools {\n display: inline-flex;\n margin-left: auto;" in css
|
||||
|
||||
Reference in New Issue
Block a user