PLAN 8-4b 열 명세를 화면에 세움. 일감 2 의 마지막 덩어리(엔진 → API → 화면). 왜 실무 서식 그대로인가 이 화면의 첫 사용자는 「프로그램이 맞나」를 확인하려는 설계자임. 보기 좋게 재배치하면 실무 산출서와 눈으로 대조를 못 함. 열 순서·머리글 문구를 실무 토적표(= 오솔길 1.BOM 36열)에 맞춤. 소수 자리는 표기 규칙일 뿐 (PLAN 8-16) 서버는 전정밀 값을 주고 자르는 것은 화면뿐임. 실무 시트 관측대로 단면적·체적 2자리 · 보정량계·유용토·차인·누가 1자리 · 거리 정수. 원가 쪽(줄마다 원 단위 절사)과 규칙이 반대라 그 코드를 옮기지 말 것. 구성 좌측 = 산출 조건 읽기 전용(산출법·토량환산계수). 계수는 서버 상수가 유일 정의처라 화면이 값을 다시 적지 않음. 우측 = 시트 탭 + 표. 지금 서는 장은 토적표 하나, 나머지 6장은 차례로 붙임. 표는 한 번만 받아 좌측·우측이 함께 씀(중복 호출 없음). 측점 열·머리글은 sticky — 가로로 굴러도 어느 줄인지 보임. locale 은 B08 키 8개만 추가 (다른 창과 겹치는 파일이라 기존 줄 무접촉). 검증 — 공용 브라우저 실화면. 타입검사 오류 0. 탭 「토적표」, 3단 머리글 3행(9/5/14셀), 본문 65행 x 20열, 합계행 표시. 둘째 줄이 API 값과 일치: NO.1 거리 20 · 절토토사 1.96/22.34/20.10 · 암 2.54/25.43/29.24 · 측구 0.08/2.58/2.33 + 0.10/1.02/1.17 · 보정량계 52.8 · 성토 4.82/48.79 · 유용 48.8 · 차인 4.0 · 누가 4.0. ⚠ 어두운 테마에서 머리글이 묻히던 것을 프로젝트 테마 변수로 바꿔 고침 — 대비 실측 머리글 10.51:1 · 본문 11.32:1 (기준 4.5:1). 조작으로 바꾼 화면은 사용자가 보던 주소로 되돌려 놓음. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
98 lines
3.2 KiB
TypeScript
98 lines
3.2 KiB
TypeScript
/* =============================================================================
|
|
* B08_Quantity_UI_EarthworkGrid_Style.ts
|
|
* 토적표 그리드 스타일. 한 번만 주입한다.
|
|
*
|
|
* 실무 산출서와 눈으로 대조되는 것이 이 표의 목적이라, 장식보다 **줄·칸이 또렷한 것**을
|
|
* 우선한다. 숫자는 등폭으로 두어 자릿수가 세로로 맞는다.
|
|
* ========================================================================== */
|
|
|
|
const STYLE_ID = "b08-earthwork-grid-style";
|
|
|
|
/* 색은 전부 프로젝트 테마 변수를 쓴다 — 어두운 테마에서 머리글이 묻히지 않아야 한다.
|
|
글자색을 배경과 함께 지정하는 까닭이 그것이다(배경만 주면 상속색이 배경에 잠긴다). */
|
|
const CSS = `
|
|
.b08-grid { display: flex; flex-direction: column; gap: 8px; min-width: 0; height: 100%; }
|
|
|
|
.b08-grid__caption {
|
|
margin: 0;
|
|
font-size: 12px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
/* 열이 많아 화면을 넘친다 — 표만 가로로 구르고 페이지 몸통은 안 구른다. */
|
|
.b08-grid__scroll { overflow: auto; flex: 1 1 auto; min-height: 0; }
|
|
|
|
.b08-grid__table {
|
|
border-collapse: collapse;
|
|
font-size: 12px;
|
|
font-variant-numeric: tabular-nums;
|
|
white-space: nowrap;
|
|
color: var(--color-text-body);
|
|
}
|
|
|
|
.b08-grid__table th,
|
|
.b08-grid__table td {
|
|
border: 1px solid var(--color-border);
|
|
padding: 2px 8px;
|
|
text-align: right;
|
|
}
|
|
|
|
.b08-grid__table thead th {
|
|
position: sticky;
|
|
top: 0;
|
|
background: var(--color-surface-raised);
|
|
color: var(--color-text);
|
|
font-weight: var(--font-weight-medium, 600);
|
|
text-align: center;
|
|
z-index: 1;
|
|
}
|
|
|
|
/* 측점 열은 왼쪽에 붙어 있어야 가로로 굴러도 어느 줄인지 보인다. */
|
|
.b08-grid__station {
|
|
position: sticky;
|
|
left: 0;
|
|
background: var(--color-surface);
|
|
color: var(--color-text);
|
|
text-align: left;
|
|
font-weight: var(--font-weight-medium, 500);
|
|
}
|
|
|
|
.b08-grid__table tfoot td {
|
|
background: var(--color-surface-raised);
|
|
color: var(--color-text);
|
|
font-weight: var(--font-weight-medium, 600);
|
|
}
|
|
|
|
.b08-quantity__tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--color-border); }
|
|
|
|
.b08-quantity__tab {
|
|
padding: 4px 12px;
|
|
font-size: 13px;
|
|
border: 1px solid var(--color-border);
|
|
border-bottom: none;
|
|
background: var(--color-surface-raised);
|
|
color: var(--color-text-secondary);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.b08-quantity__tab.is-active {
|
|
background: var(--color-surface);
|
|
color: var(--color-text);
|
|
font-weight: var(--font-weight-medium, 600);
|
|
}
|
|
|
|
.b08-quantity__body { display: flex; flex-direction: column; gap: 8px; padding: 8px; min-height: 0; flex: 1 1 auto; }
|
|
.b08-quantity__message { margin: 0; padding: 16px; font-size: 13px; color: var(--color-text-secondary); }
|
|
.b08-quantity__field { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; padding: 2px 0; }
|
|
.b08-quantity__field-value { color: var(--color-text-secondary); font-variant-numeric: tabular-nums; }
|
|
`;
|
|
|
|
/** 스타일을 한 번만 넣는다 — 페이지를 다시 그려도 중복되지 않는다. */
|
|
export function injectEarthworkGridStyles(): void {
|
|
if (document.getElementById(STYLE_ID)) return;
|
|
const style = document.createElement("style");
|
|
style.id = STYLE_ID;
|
|
style.textContent = CSS;
|
|
document.head.append(style);
|
|
}
|