Merge remote-tracking branch 'origin/dev' into sub_laptop_7
This commit is contained in:
@@ -23,13 +23,18 @@ export interface SummaryRow {
|
||||
}
|
||||
|
||||
export function buildSummaryRow(): SummaryRow {
|
||||
// 옵션 칸과 같은 2행 꼴(54-17) — 위 제목(`b05-route__field > span`) · 아래 [이름 칸][선택][해제]
|
||||
const root = document.createElement("div");
|
||||
root.className = "b05-structure__summary";
|
||||
root.className = "b05-route__field b05-structure__summary";
|
||||
root.dataset.b05Summary = "row";
|
||||
const label = document.createElement("span");
|
||||
label.className = "b05-structure__summary-label";
|
||||
label.textContent = "집계 항목";
|
||||
const name = document.createElement("span");
|
||||
label.textContent = "구조물 조합";
|
||||
// 이름 = 읽기 전용 입력 칸 — 옵션 입력 칸과 글꼴 · 크기 · 칸 모양이 같음
|
||||
const name = document.createElement("input");
|
||||
name.type = "text";
|
||||
name.readOnly = true;
|
||||
name.tabIndex = -1;
|
||||
name.className = "b05-structure__summary-name";
|
||||
const pick = document.createElement("button");
|
||||
pick.type = "button";
|
||||
@@ -41,12 +46,15 @@ export function buildSummaryRow(): SummaryRow {
|
||||
clear.className = "b05-route__irregular-btn";
|
||||
clear.textContent = "해제";
|
||||
clear.dataset.b05Summary = "clear";
|
||||
root.append(label, name, pick, clear);
|
||||
const line = document.createElement("div");
|
||||
line.className = "b05-route__irregular-actions";
|
||||
line.append(name, pick, clear);
|
||||
root.append(label, line);
|
||||
|
||||
let current: SummaryItem | null = null;
|
||||
const set = (item: SummaryItem | null): void => {
|
||||
current = item;
|
||||
name.textContent = summaryLabel(item);
|
||||
name.value = summaryLabel(item);
|
||||
name.title = summaryTooltip(item);
|
||||
name.classList.toggle("is-assigned", item !== null);
|
||||
clear.disabled = item === null;
|
||||
|
||||
@@ -439,33 +439,16 @@
|
||||
border-color: var(--color-warning, #c98a00);
|
||||
}
|
||||
|
||||
/* 집계 항목 줄(PLAN 21-4) — 옵션 · 시설 서브폼 아래 [이름][고르기][해제] 한 줄. 이름이 남는 폭을
|
||||
* 먹고 말줄임 · 키는 툴팁에만. 지정되면 성공색(`.is-assigned`) — 목록 줄과 같은 색. */
|
||||
.b05-structure__summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-8);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* 구조물 조합 잇기 줄(PLAN 21-4 · 54-17) — 옵션 칸 꼴(`b05-route__field`) 2행 · 아래 줄은
|
||||
* [이름 칸][선택][해제] · 이름 칸이 남는 폭을 먹고 말줄임 · 키는 툴팁에만. 지정되면 성공색. */
|
||||
.b05-structure__summary[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.b05-structure__summary-label {
|
||||
flex: none;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--text-caption);
|
||||
}
|
||||
|
||||
.b05-structure__summary-name {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--text-caption);
|
||||
align-self: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 글자는 성공색에 본문색을 섞어 대비 4.5 를 넘김(성공색 그대로는 밝은 테마에서 4.4). */
|
||||
|
||||
@@ -175,3 +175,9 @@
|
||||
|
||||
(10-6 사용자 · 추가항목)
|
||||
B05에서 3D 영역의 상단 버튼들 중 원근으로, 직교로 버튼의 제목은 원근, 직교 로 변경하고 기본값을 직교로 변경해줘.
|
||||
|
||||
(10-6 사용자 · 추가항목)
|
||||
- B05의 3D 영역에서 Front, Side버튼의 방향이 대각선 방향인것같아. 방향 재설정 해줘.
|
||||
|
||||
(10-6 사용자 · 추가 요청)
|
||||
- 페이지의 좌측 패널의 공통항목으로 들어온 버튼 세트의 버튼 크기가 조금 이상함. 점검
|
||||
|
||||
@@ -199,9 +199,10 @@ out.pipeSet = merge.mergeFacilityOptions(pipePrev, {
|
||||
const row = buildSummaryRow();
|
||||
const clicks = [];
|
||||
row.bind({ pick: () => clicks.push("pick"), clear: () => clicks.push("clear") });
|
||||
const [labelNode, nameNode, pickBtn, clearBtn] = row.root.children;
|
||||
const [labelNode, line] = row.root.children;
|
||||
const [nameNode, pickBtn, clearBtn] = line.children;
|
||||
out.rowEmpty = {
|
||||
name: nameNode.textContent,
|
||||
name: nameNode.value,
|
||||
assigned: nameNode.classList.contains("is-assigned"),
|
||||
clearDisabled: clearBtn.disabled,
|
||||
get: row.get(),
|
||||
@@ -211,18 +212,18 @@ out.rowEmpty = {
|
||||
};
|
||||
row.set(A);
|
||||
out.rowSet = {
|
||||
name: nameNode.textContent,
|
||||
name: nameNode.value,
|
||||
assigned: nameNode.classList.contains("is-assigned"),
|
||||
clearDisabled: clearBtn.disabled,
|
||||
title: nameNode.title,
|
||||
key: row.get().key,
|
||||
nameShowsKey: nameNode.textContent.includes("SS000007"),
|
||||
nameShowsKey: nameNode.value.includes("SS000007"),
|
||||
};
|
||||
pickBtn.click();
|
||||
clearBtn.click();
|
||||
out.clicks = clicks;
|
||||
row.set(null);
|
||||
out.rowCleared = { name: nameNode.textContent, clearDisabled: clearBtn.disabled };
|
||||
out.rowCleared = { name: nameNode.value, clearDisabled: clearBtn.disabled };
|
||||
|
||||
// 목록 줄 — 지정 색 · 툴팁
|
||||
const list = new FakeNode("ul");
|
||||
|
||||
@@ -80,7 +80,7 @@ def test_집계_항목_줄(out):
|
||||
True,
|
||||
None,
|
||||
)
|
||||
assert (empty["label"], empty["pick"], empty["clear"]) == ("집계 항목", "선택", "해제")
|
||||
assert (empty["label"], empty["pick"], empty["clear"]) == ("구조물 조합", "선택", "해제")
|
||||
row = out["rowSet"]
|
||||
assert row["assigned"] is True and row["clearDisabled"] is False
|
||||
assert row["name"] == "돌기슭막이 메쌓기 1.2m" and A_KEY in row["title"]
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
c: b.dataset.specContainer,
|
||||
legend: b.querySelector("legend").firstChild.textContent,
|
||||
items: [...b.querySelectorAll("[data-spec-item]")].map((n) => n.dataset.specItem),
|
||||
link: b.querySelector(".b05-structure__summary-name")?.textContent,
|
||||
link: b.querySelector(".b05-structure__summary-name")?.value,
|
||||
}));
|
||||
const linkName = (c, i = 0) =>
|
||||
box(c, i).querySelector(".b05-structure__summary-name").classList.contains("is-assigned");
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
values: [...b.querySelectorAll("[data-spec-item]")].map(
|
||||
(n) => n.querySelector("select, input").value,
|
||||
),
|
||||
link: b.querySelector(".b05-structure__summary-name")?.textContent,
|
||||
link: b.querySelector(".b05-structure__summary-name")?.value,
|
||||
}));
|
||||
const linked = (c) =>
|
||||
box(c).querySelector(".b05-structure__summary-name").classList.contains("is-assigned");
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
n.dataset.specItem,
|
||||
n.querySelector("select, input").value,
|
||||
]),
|
||||
link: b.querySelector(".b05-structure__summary-name")?.textContent,
|
||||
link: b.querySelector(".b05-structure__summary-name")?.value,
|
||||
}));
|
||||
const assigned = (c) =>
|
||||
box(c).querySelector(".b05-structure__summary-name").classList.contains("is-assigned");
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
summaryRightAfterPosition: after === summary,
|
||||
anchor: vis(anchorWrap),
|
||||
stale: vis(sec().querySelector(".b05-structure__stale")),
|
||||
linked: summary.querySelector(".b05-structure__summary-name")?.textContent ?? "",
|
||||
linked: summary.querySelector(".b05-structure__summary-name")?.value ?? "",
|
||||
};
|
||||
};
|
||||
const pickType = async (typeId) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* 52-6 — 횡단배수 › 맹암거(표 06 · 새 종류 `cross_underdrain`) · B05 · B06 「구조물 배치」
|
||||
/* 52-6 — 횡단배수 › 맹암거(표 06 · 새 종류 `cross_underdrain`) · B05 · B06 「구조물 배치」
|
||||
* 시작 화면: B05 종단설계(#/b05-profile) · 아무것도 안 고름 · 측점 3+7 이 비어 있음
|
||||
* 부르는 법: 단계마다 한 번씩 — 앞에 `window.__m526 = "단계";` 를 붙여
|
||||
* orca eval --expression "window.__m526='edit'; $(cat 이 파일)" → 종류 목록 · 컨테이너 · 값 · 잇기 · [추가] · 다시 열기
|
||||
@@ -53,7 +53,7 @@
|
||||
(n) => `${n.dataset.optionKeys}|${n.querySelector("span").textContent}`,
|
||||
),
|
||||
values: ["culvert_height_m", "culvert_slope_pct"].map((k) => input(k)?.value),
|
||||
link: b?.querySelector(".b05-structure__summary-name").textContent,
|
||||
link: b?.querySelector(".b05-structure__summary-name").value,
|
||||
linked: b?.querySelector(".b05-structure__summary-name").classList.contains("is-assigned"),
|
||||
linkRows: [...sec().querySelectorAll("[data-b05-summary=row]")].filter(vis).length,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/* 54-17 — B05 · B06 좌측 「구조물 배치」 구조물 조합 잇기 줄 = 옵션 칸 꼴 2행
|
||||
* 시작 화면: B05 종단설계(#/b05-profile) 또는 B06 횡단설계(#/b06-section) · 검증 프로젝트(랩탑_보조)
|
||||
* 부르는 법: 한 번 — 배관 · 맹암거 · 반사경 · 옹벽을 폼에서 골라(저장 안 함) 보이는 잇기 줄을 잼 ·
|
||||
* 결과를 sessionStorage `m5417` 에 page 별로 두고 B05 = B06 을 견줌 · 끝나면 폼 고르기를 비움
|
||||
* 판정: 제목 · 값 두 줄(제목 아래 = 값) · 제목 글꼴/크기/색 = 옵션 칸 제목 · 값 글꼴/크기/높이/테두리 = 입력 칸
|
||||
* 쓰는 것: 없음(폼 고르기만 · 저장 안 함)
|
||||
*/
|
||||
(async () => {
|
||||
const w = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
const page = location.hash.includes("b06") ? "B06" : "B05";
|
||||
const sec = document.querySelector(".b05-structure-section");
|
||||
const [g, t] = sec.querySelectorAll(".b05-structure__grid select");
|
||||
const pick = async (el, v) => {
|
||||
el.value = v;
|
||||
el.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
await w(400);
|
||||
};
|
||||
const vis = (el) => !!el && el.getClientRects().length > 0;
|
||||
const cs = (el) => getComputedStyle(el);
|
||||
const font = (el) => [cs(el).fontFamily, cs(el).fontSize, cs(el).color].join("|");
|
||||
const box = (el) =>
|
||||
[
|
||||
cs(el).fontFamily,
|
||||
cs(el).fontSize,
|
||||
cs(el).height,
|
||||
cs(el).padding,
|
||||
cs(el).borderTopWidth,
|
||||
cs(el).borderRadius,
|
||||
].join("|");
|
||||
const TARGETS = {
|
||||
배관: ["A", "pipe"],
|
||||
맹암거: ["A", "cross_underdrain"],
|
||||
반사경: ["E", "mirror"],
|
||||
옹벽: ["C", "retaining_wall"],
|
||||
};
|
||||
const out = {};
|
||||
for (const [name, [gv, tv]] of Object.entries(TARGETS)) {
|
||||
await pick(g, gv);
|
||||
await pick(t, tv);
|
||||
const rows = [...sec.querySelectorAll("[data-b05-summary=row]")].filter(vis);
|
||||
const cap = [...sec.querySelectorAll(".b05-route__field > span")].find(
|
||||
(s) => vis(s) && !s.closest("[data-b05-summary]"),
|
||||
);
|
||||
const input = [
|
||||
...sec.querySelectorAll(".b05-route__field input, .b05-route__field select"),
|
||||
].find((i) => vis(i) && !i.closest("[data-b05-summary]") && i.type !== "checkbox");
|
||||
out[name] = rows.map((r) => {
|
||||
const title = r.children[0];
|
||||
const nameEl = r.querySelector(".b05-structure__summary-name");
|
||||
return {
|
||||
title: title.textContent,
|
||||
value: nameEl.value,
|
||||
twoLines: title.getBoundingClientRect().bottom <= nameEl.getBoundingClientRect().top,
|
||||
titleFont: font(title) === font(cap),
|
||||
valueBox: box(nameEl) === box(input),
|
||||
buttons: [...r.querySelectorAll("button")].map((b) => b.textContent).join(","),
|
||||
fonts: { title: font(title), value: box(nameEl) },
|
||||
};
|
||||
});
|
||||
}
|
||||
await pick(g, "");
|
||||
const store = JSON.parse(sessionStorage.getItem("m5417") || "{}");
|
||||
store[page] = out;
|
||||
sessionStorage.setItem("m5417", JSON.stringify(store));
|
||||
const strip = (o) => JSON.stringify(o, (k, v) => (k === "value" ? undefined : v));
|
||||
const same = store.B05 && store.B06 ? strip(store.B05) === strip(store.B06) : null;
|
||||
return JSON.stringify({ page, out, B05eqB06: same });
|
||||
})();
|
||||
@@ -79,7 +79,7 @@
|
||||
typeRows: [...section().querySelectorAll(".b05-structure__summary")].filter(
|
||||
(n) => !n.closest("[data-b05-group]") && visible(n),
|
||||
).length,
|
||||
link: box?.querySelector(".b05-structure__summary-name")?.textContent.trim(),
|
||||
link: box?.querySelector(".b05-structure__summary-name")?.value.trim(),
|
||||
};
|
||||
};
|
||||
const ok = (type, s) =>
|
||||
|
||||
Reference in New Issue
Block a user