feat(804-5): 줄 쌓기 왼쪽 손질 — 자원 이름 단추 · 항목 띠 · 끌어 옮기기 · X 지움 되돌리기 · 율 번지 읽는 이름
- 인력 · 기계 · 재료 · 단가산출 줄 자원 이름 = 단추(이름 · 규격) → 찾아 넣기 창 → 바꿈 · [찾아 바꾸기] 걷음 - 항목 머리 = 띠(바탕 · 왼쪽 굵은 띠 · 번호) · 줄 = 들여쓰기 + 왼쪽 세로 선 · 가나다 한 단 더 · 접기 - 순서 = 손잡이 끌기(줄 = 항목 안 · 사이 · 항목 끌기 · 자리 선 표시) · [↑][↓] 걷음 - 지움 = X 아이콘 · 확인 없이 지우고 알림 눌러 되돌리기(그 뒤 고침 있으면 못 함) - 산출근거 율 줄 「번지.복사N.노무비」 → 그 조각 이름 · 값 식 = 번지 값 · 합계 덧셈 항 넷 넘으면 항목 소계끼리 - 알림 부품: 누름 동작 알림은 같은 문구 버림 안 함(두 번째 지움 되돌리기 안 뜨던 흠) - 글 · 근거 카드 높이 늘던 흠 고침 · 시험 test_804_4 끌어옮김 · 번지 이름 더함 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -318,6 +318,19 @@ export function dropSyms(doc: FormulaDoc, ids: string[]): void {
|
||||
doc.식 = (doc.식 ?? []).filter((l) => !gone.has(String(l.기호 ?? "")));
|
||||
}
|
||||
|
||||
/** 끌어 옮김(804-5) — 줄 `[i, j]` → 항목 k 의 p 자리(빼기 전 차례 · 같은 항목 아래로면 하나 당김) */
|
||||
export function moveLine(items: StackItem[], i: number, j: number, k: number, p: number): void {
|
||||
const [line] = items[i].줄.splice(j, 1);
|
||||
if (!line || !items[k]) return void (line && items[i].줄.splice(j, 0, line));
|
||||
items[k].줄.splice(Math.min(i === k && p > j ? p - 1 : p, items[k].줄.length), 0, line);
|
||||
}
|
||||
|
||||
/** 끌어 옮김(804-5) — 항목 i → p 자리(빼기 전 차례) */
|
||||
export function moveItem<T>(items: T[], i: number, p: number): void {
|
||||
const [it] = items.splice(i, 1);
|
||||
if (it !== undefined) items.splice(Math.min(p > i ? p - 1 : p, items.length), 0, it);
|
||||
}
|
||||
|
||||
/** 공식 줄 값 · 식 고침 — 수 = 숫자 연결 · 식 = 식 줄 */
|
||||
export function setRow(doc: FormulaDoc, id: string, text: string): void {
|
||||
const t = text.trim().replace(/,/g, "");
|
||||
|
||||
@@ -195,3 +195,29 @@ export function addTaken(doc: StackDoc, items: StackItem[], t: Taken): void {
|
||||
for (const r of rates) pushMoney({ ...r, 단가: rescope(r.단가, places) as string });
|
||||
}
|
||||
}
|
||||
|
||||
/** 번지 읽는 이름(804-5) — 산출근거 「번지.복사N.노무비」 대신 · 그 번지 줄만 든 항목 제목 · 없으면 줄 이름(둘까지 · 「외 n」) */
|
||||
export function placeNames(doc: StackDoc, items: StackItem[]): Record<string, string> {
|
||||
const money = doc.금액 ?? [];
|
||||
const out: Record<string, string> = {};
|
||||
for (const p of new Set(money.map((l) => String(l.번지 ?? "")).filter(Boolean))) {
|
||||
const mine = (l: StackLine): boolean => l.꼴 === "금액" && money[l.i]?.번지 === p;
|
||||
const holds = items.filter((it) => it.줄.some(mine));
|
||||
const only = holds.every((it) =>
|
||||
it.줄.every((l) => l.꼴 !== "금액" || mine(l) || !money[l.i]?.번지),
|
||||
);
|
||||
let title = only ? (holds.find((it) => it.제목.trim())?.제목.trim() ?? "") : "";
|
||||
// 여러 항목에 걸친 조각 = 첫 항목 「조각 이름 · 항목 제목」의 조각 이름(addTaken 꼴)
|
||||
// ponytail: 항목 제목에 「 · 」가 있으면 덜 자름 — 조각 이름을 문서에 따로 적게 되면 그것으로
|
||||
if (title && holds.length > 1 && title.lastIndexOf(" · ") > 0)
|
||||
title = title.slice(0, title.lastIndexOf(" · "));
|
||||
const lines = money.filter((l) => l.번지 === p).map((l) => String(l.이름 ?? "").trim());
|
||||
out[p] =
|
||||
title ||
|
||||
(lines.length > 2
|
||||
? `${lines[0]} 외 ${lines.length - 1}`
|
||||
: lines.filter(Boolean).join(" · ")) ||
|
||||
p;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user