feat(est-test): 설명서·시방서 글자모양과 전체삭제

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-12 13:18:22 +09:00
co-authored by Claude Opus 5.5
parent 04cba1082c
commit 053fc83ccf
2 changed files with 25 additions and 1 deletions
+1
View File
@@ -518,6 +518,7 @@ ative-standard.js에 표준시장단가 원천(SilJukDat)과 내역 행(EstMainD
- 검증완료: 문서·바인딩 시험 4개 통과. ORCA 브라우저에서 갑지 공사위치 「X위치」 양식 저장·기본양식 저장 → 초기화 뒤 다시 열면 「X위치」 채움, 양식목록에서 불러오기, 인쇄 → 미리보기 서식 8 에 갑지, 양식·인쇄 설정 지워 복구.
- [x] 공사설명서·시방서 서식 편집(원본 TFRMESTEDITOR mnuFormatPar·mnuTableCreate·mnuFormatTable·popupBookMark·mnuFormatTableS·mnuSaveToDefault) — 서식 있는 편집 칸: 문단모양(정렬·들여쓰기·왼쪽 여백·줄간격), 표만들기(줄·칸), 표모양(테두리·칸 여백·너비), 책갈피(넣기·찾아가기), 양식목록(서버 양식 보관함 종류 document — 불러오기·지우기·현재 문서 저장), 기본양식으로 저장(빈 문서를 열면 채움). 본문은 `docs[kind].html`(허용 태그·속성만)과 글자 `text` 를 함께 두고 인쇄는 html 우선. 갑지에서 붙여넣기는 커서 자리에. 원본 WPT 서식 가져오기·ESTX 저장은 여전히 하지 않음.
- 검증완료: 문서·바인딩 시험 4개 통과. ORCA 브라우저에서 설명서 첫 문단 가운데 정렬, 3×3 표·테두리 2px, 공사명 붙여넣기, 저장 뒤 인쇄 html 에 표·정렬 반영, 기본양식 저장 → 빈 문서 열 때 표 채움, 양식·문서 지워 복구. (DOM 이 필요해 pytest 단위 시험은 없음)
- [x] 글자모양(mnuformatFont: 굵게·기울임·밑줄·크기 pt)·전체삭제(mnuAllDelete). 검증완료: ORCA 브라우저에서 「나다」 10pt span 유지(허용 속성), 전체삭제 뒤 빈 문단, 저장 안 하고 닫음.
- [x] 원가계산서 산출근거 약어로 표시(원본 popupSNameShow 0xd0e494 · 약어 생성 0xc97790) — 원가계산서(W) 메뉴 단추로 켜고 끔. 산출근거 식의 기호(영문 시작 또는 2자 이하, 범위 기호 뒤 제외)를 그 행 약어(SName, 없으면 빈칸 뺀 이름)로, 숫자×100 이 그 행 요율이면 요율 글자로, 「:」 는 「~」 로 바꿔 화면·인쇄에 보이고 그동안 산출근거 칸 잠금. 저장 값(VSusic)은 그대로. 기성 원가 화면의 같은 확인란과 같은 설정.
- 검증완료: `test_est_wonga_tools.py` 5개(샘플 「직.노 × 16.5%」·「( 산출경비 ~ 18 )」·「순.공 × 8%」, 번호 열쇠, 원본 식 불변) 통과. ORCA 브라우저에서 켜기 → 약어 표시·입력칸 0, 끄기 → 입력칸 31, 설정 지워 복구.
- [x] 발췌근거(원본 barbtnColumn — TfrmHeaderChange 0x110b7ec · 자재 TfrmStuffcHeadChange 0xf61b84) — 자재·노임 화면 「발췌근거」 단추로 출처 열(Cost1~6) 이름·쪽수(자재)·보기 편집, 자재는 8가지 출처 이름에서 고르고 중복 거부, 숨긴 출처는 최저·평균·최고 단가 고르기에서 빠짐(서버 재계산도 같은 코드). 값은 계산 환경 `PriceSources`(ESTX 저장에는 남지 않음 — 원본도 출처 이름은 격자 배치에만 둠).
+24 -1
View File
@@ -29,7 +29,7 @@ const EstDocEditor = (() => {
"LI",
]);
const STYLE =
/^(text-align|text-indent|line-height|margin-left|border|border-collapse|padding|width|font-weight|font-style|text-decoration)$/;
/^(text-align|text-indent|line-height|margin-left|border|border-collapse|padding|width|font-weight|font-style|text-decoration|font-size)$/;
const DEFAULT = { explan: "기본양식-설명서", sibang: "기본양식-시방서" };
// 허용 태그·속성만 남김(id 는 책갈피, style 은 정해진 속성만)
@@ -84,6 +84,7 @@ const EstDocEditor = (() => {
function body(d) {
return `<div class="business-tools">${[
["doc-font", "글자모양"],
["doc-par", "문단모양"],
["doc-table", "표만들기"],
["doc-table-style", "표모양"],
@@ -234,6 +235,25 @@ const EstDocEditor = (() => {
rich()
.querySelector(`a[id="${CSS.escape(node.dataset.mark)}"]`)
?.scrollIntoView({ block: "center" });
} else if (name === "doc-font") {
remember();
panel(
`글자모양 <button data-action="doc-font-ok" data-cmd="bold"><b>굵게</b></button><button data-action="doc-font-ok" data-cmd="italic"><i>기울임</i></button><button data-action="doc-font-ok" data-cmd="underline"><u>밑줄</u></button> 크기(pt) <input name="size" type="number" value="10" min="6" max="40" style="width:60px"><button data-action="doc-font-ok" data-cmd="size">크기 적용</button> <button data-action="doc-clear">전체삭제</button>`,
);
} else if (name === "doc-font-ok") {
const range = restore();
if (range.collapsed) throw Error("글자를 고른 뒤 적용하세요.");
if (node.dataset.cmd === "size") {
const span = document.createElement("span");
span.style.fontSize = `${Math.min(40, Math.max(6, Number(v("size")) || 10))}pt`;
span.append(range.extractContents());
range.insertNode(span);
} else document.execCommand(node.dataset.cmd);
remember();
} else if (name === "doc-clear") {
if (!confirm("문서 내용을 모두 지우시겠습니까?")) return;
rich().innerHTML = "<p><br></p>";
panel("");
} else if (name === "doc-forms") {
const list = (await EstApp.api("/api/forms")).filter((f) => f.kind === "document");
panel(
@@ -291,6 +311,9 @@ const EstDocEditor = (() => {
"doc-form-delete",
"doc-form-save",
"doc-default",
"doc-font",
"doc-font-ok",
"doc-clear",
]);
function handle(name, state, node) {
if (!names.has(name)) return false;