feat(B05·B06): 구조물 좌측 패널 「집계 항목」 줄 · 옵션 보이기 · [수정] 옵션 보존 · 목록 지정 색(21-4)
- 폼 옵션 아래 「집계 항목」 줄(이름 · 미지정 · [고르기] · [해제]) — 구조물 · 관 계열 하위 폼 · B05 · B06 한 코드 - 옵션 `visible:false` 는 폼에서 숨김(정의 · 옛 값 그대로) · [수정]은 폼이 그린 칸만 갈아 끼우고 안 그린 칸(상세 · 숨긴 칸) 보존 — 옵션 덮어쓰기 흠 고침 - 목록 줄 `.is-assigned` 색 · 툴팁 항목 이름 · 캐시는 지금 초안 기록 칸(structures · pipes) 안 summary_item - 미지정이면 칸을 안 실음 · 관은 서버 응답에 칸이 없으면 같은 측점에서 화면이 이어받음 - 항목 고르기 모달은 21-5 가 오기 전까지 같은 이름의 임시 함수 · Structures_Panel 700줄 넘어 옵션 그리기를 Panel_Options 로 나눔 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TULoa94ZFL26KU6ZqVpjkF
This commit is contained in:
@@ -17,6 +17,8 @@ import type { PipeFacility } from "../B04_PreProcess/B04_PreProcess_Api_Fetch";
|
||||
import type { FacilityAttributes, FacilityOptionsForm } from "./B05_Profile_UI_Drainage_Facility";
|
||||
import type { StationFields } from "./B05_Profile_UI_Structures_Fields";
|
||||
import { splitPavementRange } from "./B05_Profile_UI_Structures_Pavement";
|
||||
import { mergeStructureOptions } from "./B05_Profile_UI_Structures_Summary";
|
||||
import { readSummaryItem, type SummaryItem } from "../common_util/common_util_summary_item";
|
||||
import type {
|
||||
PipeFacilityItem,
|
||||
StructuresCallbacks,
|
||||
@@ -64,6 +66,9 @@ export interface StructuresCommitContext {
|
||||
setPositionConfirmed: (value: boolean) => void;
|
||||
tempPipeChainage: () => number | null;
|
||||
setTempPipeChainage: (value: number | null) => void;
|
||||
/** 폼의 「집계 항목」 값(PLAN 21-4) — 저장은 옵션 밖 `summary_item` 칸으로 나간다. */
|
||||
summary: () => SummaryItem | null;
|
||||
setSummary: (value: SummaryItem | null) => void;
|
||||
}
|
||||
|
||||
export function loadForm(ctx: StructuresCommitContext, target: StructureInstance | null): void {
|
||||
@@ -85,6 +90,7 @@ export function loadForm(ctx: StructuresCommitContext, target: StructureInstance
|
||||
ctx.endFields.write(target.end_m ?? null, step);
|
||||
ctx.memoField.value = target.memo ?? "";
|
||||
ctx.renderOptionFields(target.options);
|
||||
ctx.setSummary(readSummaryItem(target.summary_item));
|
||||
// 구간 직접 입력 시절에 저장된 항목 호환 — 길이·전길이 옵션이 없으면 저장된
|
||||
// 시작~종료·기준점에서 역산해 채워 범위 표시·재저장이 이어지게 한다(2026-08-19).
|
||||
if (target.start_m != null && target.end_m != null && target.end_m > target.start_m) {
|
||||
@@ -112,6 +118,7 @@ export function loadForm(ctx: StructuresCommitContext, target: StructureInstance
|
||||
ctx.endFields.write(null, step);
|
||||
ctx.memoField.value = "";
|
||||
ctx.renderOptionFields();
|
||||
ctx.setSummary(null);
|
||||
ctx.syncFacilityForm();
|
||||
}
|
||||
[ctx.anchorFields, ctx.startFields, ctx.endFields].forEach((fields) => fields.clearInvalid());
|
||||
@@ -158,6 +165,7 @@ export function loadPipeForm(ctx: StructuresCommitContext, pipe: PipeFacilityIte
|
||||
ctx.endFields.write(null, step);
|
||||
ctx.memoField.value = "";
|
||||
ctx.syncFacilityForm(pipe.options ?? {}, pipe.design_flow_m3s ?? null);
|
||||
ctx.setSummary(readSummaryItem(pipe.summary_item));
|
||||
[ctx.anchorFields, ctx.startFields, ctx.endFields].forEach((fields) => fields.clearInvalid());
|
||||
ctx.syncPlacementFields();
|
||||
ctx.syncButtons();
|
||||
@@ -199,6 +207,8 @@ export async function commit(ctx: StructuresCommitContext, live = false): Promis
|
||||
const attributes: FacilityAttributes = { facility: type.type_id as PipeFacility };
|
||||
const options = ctx.facilityOptions.readOptions();
|
||||
if (Object.keys(options).length) attributes.options = options;
|
||||
// 집계 항목 — 미지정(null)도 그대로 실어 옛 지정을 풀 수 있게 한다.
|
||||
attributes.summary_item = ctx.summary();
|
||||
if (ctx.tempPipeChainage() !== null) {
|
||||
// 임시 배치 확정([추가]) — 관은 이미 미리보기로 들어가 있으니 옵션·위치만 반영.
|
||||
const from = ctx.tempPipeChainage() as number;
|
||||
@@ -271,6 +281,7 @@ export async function commit(ctx: StructuresCommitContext, live = false): Promis
|
||||
return;
|
||||
}
|
||||
|
||||
const summary = ctx.summary();
|
||||
const base = {
|
||||
type_id: type.type_id,
|
||||
placement,
|
||||
@@ -278,6 +289,7 @@ export async function commit(ctx: StructuresCommitContext, live = false): Promis
|
||||
start_m: start,
|
||||
end_m: end,
|
||||
options: readOptions(ctx),
|
||||
...(summary ? { summary_item: summary } : {}),
|
||||
memo: ctx.memoField.value.trim(),
|
||||
placement_source: "manual" as const,
|
||||
status: "draft" as const,
|
||||
@@ -304,7 +316,23 @@ export async function commit(ctx: StructuresCommitContext, live = false): Promis
|
||||
|
||||
if (ctx.editingId()) {
|
||||
const index = ctx.structures.findIndex((entry) => entry.structure_id === ctx.editingId());
|
||||
if (index >= 0) ctx.structures[index] = { ...ctx.structures[index], ...records[0] };
|
||||
if (index >= 0) {
|
||||
// [수정] = 폼이 그린 칸만 갈아 끼우고 나머지(안 보이는 칸 · 상세 칸)는 옛 값 보존.
|
||||
const previous = ctx.structures[index];
|
||||
const next: StructureInstance = {
|
||||
...previous,
|
||||
...records[0],
|
||||
options: mergeStructureOptions(
|
||||
previous,
|
||||
type.type_id,
|
||||
ctx.optionInputs.map((entry) => entry.key),
|
||||
records[0].options,
|
||||
),
|
||||
};
|
||||
// 해제 = 칸을 지움(옛 지정이 `...previous` 로 살아 오지 않게)
|
||||
if (!summary) delete next.summary_item;
|
||||
ctx.structures[index] = next;
|
||||
}
|
||||
records.slice(1).forEach((record) => ctx.structures.push({ ...record, structure_id: null }));
|
||||
} else {
|
||||
records.forEach((record) => ctx.structures.push({ ...record, structure_id: null }));
|
||||
|
||||
Reference in New Issue
Block a user