fix(rebar): 부재 fck 되돌리기가 교각도 기본값으로 돌아가고, 기본과 다르면 주황색 표시
- IMPORTED_FCK(기둥 40, 코핑 40, 확대기초 27)와 fckChanged 추가, 테스트 4건 - 되돌리기는 공통 fck가 아니라 교각도 기본값으로 돌아감 (기둥·코핑은 기존에 27로 돌아가던 문제) - 기본과 다르면 입력 카드를 주황색으로 표시. "변경 n건"에는 넣지 않음 (배근에만 반영) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9a338614a6
commit
70fa0be86f
3 files changed
+41
-8
No files matched your search
@@ -91,6 +91,15 @@ export const FCK_MEMBERS: readonly FckMember[] = ['column', 'coping', 'footing']
|
||||
/** Per-member fck (MPa). A member without an entry uses the ③ 공통 설정 fck. */
|
||||
export type FckByMember = Partial<Record<FckMember, number>>;
|
||||
|
||||
/** 교각도 기준 부재별 기본 fck (MPa). 되돌리기는 이 값으로 돌아가고, 이 값과 다르면 주황색으로 표시합니다. */
|
||||
export const IMPORTED_FCK: Record<FckMember, number> = { column: 40, coping: 40, footing: 27 };
|
||||
|
||||
/** True when the member's fck is set and differs from its imported default. An unset member is not changed. */
|
||||
export function fckChanged(byMember: FckByMember, member: FckMember): boolean {
|
||||
const value = byMember[member];
|
||||
return value !== undefined && value !== IMPORTED_FCK[member];
|
||||
}
|
||||
|
||||
/** The material a member is designed with: its own fck when set, otherwise the 공통 value. fy stays common. */
|
||||
export function materialFor(common: Material, byMember: FckByMember, member: FckMember): Material {
|
||||
return { ...common, fck: byMember[member] ?? common.fck };
|
||||
|
||||
+9
-8
@@ -14,7 +14,7 @@ import { pileGeometry } from './core/geometry';
|
||||
import { rebarSummary, type RebarRow } from './core/rebar/summary';
|
||||
import { shearSegments } from './core/rebar/coping';
|
||||
import { buildRebar3D, type RebarColorMode, type RebarScene } from './view/rebar3d';
|
||||
import { DEFAULT_MATERIAL, FCK_MEMBERS, fyOf, GRADE_CHOICES, isAssumedMaterial, materialFrom, type BendFactors, type FckByMember, type FckMember, type GradeKey, type Material } from './core/rebar/common';
|
||||
import { DEFAULT_MATERIAL, FCK_MEMBERS, fckChanged, fyOf, GRADE_CHOICES, IMPORTED_FCK, isAssumedMaterial, materialFrom, type BendFactors, type FckByMember, type FckMember, type GradeKey, type Material } from './core/rebar/common';
|
||||
import { buildQuantity, quantityRows, type Quantity, type QuantityLine } from './core/rebar/quantity';
|
||||
import { parseDrawingRows } from './core/drawing-import';
|
||||
import { groundElFor, parseGroundModel, strataRowsFor, type GroundModelFile } from './core/ground-model';
|
||||
@@ -125,7 +125,7 @@ const state = {
|
||||
/** ③ 공통 설정 (fck · fy). */
|
||||
material: { ...DEFAULT_MATERIAL } as Material,
|
||||
/** ② 부재별 fck. A member without an entry uses the 공통 fck (③). Initial values from 교각도 (025·026, 승인 2026-10-27): 기둥·코핑 40, 기초 27. */
|
||||
fckByMember: { column: 40, coping: 40, footing: 27 } as FckByMember,
|
||||
fckByMember: { ...IMPORTED_FCK } as FckByMember,
|
||||
/** Bar highlighted on ③ after [보기] (시안 ③ 알림). */
|
||||
/** Bars selected on ③ (철근표 checkboxes, 3D click, [보기]). */
|
||||
rebarSelection: new Set<string>(),
|
||||
@@ -1897,7 +1897,8 @@ function renderMaterial(): void {
|
||||
function setMemberFck(member: FckMember, raw: string): void {
|
||||
const next = { ...state.fckByMember };
|
||||
if (raw.trim() === '') {
|
||||
delete next[member];
|
||||
// 되돌리기: back to the imported default, not to the 공통 value.
|
||||
next[member] = IMPORTED_FCK[member];
|
||||
} else {
|
||||
const value = Number(raw);
|
||||
if (!Number.isFinite(value) || value <= 0) {
|
||||
@@ -1915,8 +1916,9 @@ function setMemberFck(member: FckMember, raw: string): void {
|
||||
/** fck row on a ② card for a member that has its own fck: value, the 공통 value beside it, and a revert when set. */
|
||||
function renderMemberFck(box: HTMLDivElement, member: FckMember): void {
|
||||
const own = state.fckByMember[member];
|
||||
// Not the orange "changed" style: fck changes only the rebar, so it is not a pending shape change (변경 n건).
|
||||
const row = el('div', undefined, 'edit-row');
|
||||
// Orange = differs from the imported default. fck changes only the rebar, so it is not counted in 변경 n건.
|
||||
const changed = fckChanged(state.fckByMember, member);
|
||||
const row = el('div', undefined, changed ? 'edit-row changed' : 'edit-row');
|
||||
const id = `member-fck-${member}`;
|
||||
const label = el('label', 'fck (MPa)');
|
||||
label.htmlFor = id;
|
||||
@@ -1926,9 +1928,8 @@ function renderMemberFck(box: HTMLDivElement, member: FckMember): void {
|
||||
input.step = 'any';
|
||||
input.value = String(own ?? state.material.fck);
|
||||
input.addEventListener('change', () => setMemberFck(member, input.value));
|
||||
const note = own === undefined ? `공통 ${state.material.fck}` : `공통 ${state.material.fck} · 배근에만 반영`;
|
||||
row.append(label, input, el('span', note, 'muted small'));
|
||||
if (own !== undefined) {
|
||||
row.append(label, input, el('span', `기본 ${IMPORTED_FCK[member]} · 배근에만 반영`, 'muted small'));
|
||||
if (changed) {
|
||||
const revert = el('button', '되돌리기', 'btn small');
|
||||
revert.type = 'button';
|
||||
revert.addEventListener('click', () => setMemberFck(member, ''));
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { fckChanged, IMPORTED_FCK } from '../src/core/rebar/common';
|
||||
|
||||
describe('IMPORTED_FCK (교각도 기준 부재별 기본 fck)', () => {
|
||||
it('is 40 for 기둥·코핑 and 27 for 확대기초', () => {
|
||||
expect(IMPORTED_FCK).toEqual({ column: 40, coping: 40, footing: 27 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('fckChanged (기본과 다르면 주황색)', () => {
|
||||
it('is false at the imported default', () => {
|
||||
expect(fckChanged({ column: 40, coping: 40, footing: 27 }, 'coping')).toBe(false);
|
||||
});
|
||||
|
||||
it('is true when the member differs from its imported default', () => {
|
||||
expect(fckChanged({ coping: 42 }, 'coping')).toBe(true);
|
||||
expect(fckChanged({ footing: 30 }, 'footing')).toBe(true);
|
||||
});
|
||||
|
||||
it('is false when the member has no value yet', () => {
|
||||
expect(fckChanged({}, 'column')).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user