feat(B05): 종단 우클릭 → [추가]까지 끝난 상태 — 필수 빈칸 없는 종류 바로 추가 + 고른 채 · 패널 폄 · 옛 잇기 비움(116-1)
- 패널 addAt(B05 종단 · B06 종단 · 3D 공용) = 새로 놓기(startNew)에서 시작 · 좌측 패널 열고 「구조물 배치」 폄 - 필수 빈칸 없는 종류 = [추가] 대신 누름 + 새 항목 고름(구조물 = 임시 id · A군 = 그 측점 관) - 필수 빈칸 · 노면공(확인창) · 세월교 · 물넘이포장(월류 높이 = 유량 뒤) = 폼만 · A군 임시 배치 그대로 - 시험 test_116_right_click_add(헬퍼 helper_116_right_click_add.cjs) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UoSr2sqvYtBf1dtQdus88s
This commit is contained in:
@@ -43,6 +43,7 @@ import {
|
||||
loadPipeForm as loadPipeFormInto,
|
||||
} from "./B05_Profile_UI_Structures_Panel_Commit";
|
||||
import { renderStructureList } from "./B05_Profile_UI_Structures_List";
|
||||
import { addsAtOnce, finishAdd } from "./B05_Profile_UI_Structures_Panel_AddAt";
|
||||
import { pickable, showsAnchor } from "./B05_Profile_UI_Structures_Define";
|
||||
import { hiddenOptionKeys } from "./B05_Profile_UI_Structures_Define_Form";
|
||||
import { stationLabel as formatStation } from "../common_util/common_util_station";
|
||||
@@ -522,7 +523,7 @@ export function createStructuresSection(
|
||||
setSummary: (value) => summary.set(value),
|
||||
groupBoxes,
|
||||
};
|
||||
bindStructuresEvents(panelContext);
|
||||
const { startNew } = bindStructuresEvents(panelContext);
|
||||
// 집계 항목(본체 · 옵션 그룹) — [고르기]는 21-5 모달 · 배선은 `_Structures_Groups`
|
||||
bindSummaryPickers({
|
||||
summary,
|
||||
@@ -635,16 +636,12 @@ export function createStructuresSection(
|
||||
addAt(chainageM, typeId) {
|
||||
const type = typeMap().get(typeId);
|
||||
if (!type) return;
|
||||
// 우클릭 추가 = 즉시 추가 폐지(2026-08-18 사용자 지시 — 옵션 확대로 바로 넣을
|
||||
// 수 없는 타입이 생겼다). 폼에 종류·측점을 자동으로 실어 옵션을 활성화하고,
|
||||
// [추가]로 확정한다. A군은 측점이 실리는 순간 임시 배치(세부유역 미리보기)까지
|
||||
// 자동으로 진행된다.
|
||||
cancelTempPipe();
|
||||
groupSelect.value = type.group;
|
||||
syncTypeOptions(typeId);
|
||||
typeSelect.value = typeId;
|
||||
editingId = null;
|
||||
selectedPipeChainage = null;
|
||||
// 우클릭 = [추가]까지 끝난 상태(116-1 · 08-18 「즉시 추가 폐지」를 바꿈) — 새로 놓기에서
|
||||
// 시작해 옛 고름 · 집계 항목 · 그룹 잇기를 비우고 패널을 열어 「구조물 배치」를 폄.
|
||||
// 필수 빈칸이 없으면 바로 추가 + 새 항목 고름 · 남으면 폼만(A군은 임시 배치까지).
|
||||
startNew(type.group, typeId);
|
||||
callbacks.onReveal?.();
|
||||
root.classList.remove("is-collapsed");
|
||||
positionConfirmed = true; // 우클릭은 측점이 확정돼 들어온다 — 옵션도 바로 연다.
|
||||
const placement = placementOf(typeId);
|
||||
const step = interval();
|
||||
@@ -653,11 +650,12 @@ export function createStructuresSection(
|
||||
anchorFields.write(chainageM, step);
|
||||
startFields.write(isInterval ? chainageM : null, step);
|
||||
endFields.write(isInterval ? chainageM + DEFAULT_INTERVAL_LENGTH_M : null, step);
|
||||
memoField.value = "";
|
||||
syncPlacementFields();
|
||||
// 새 구조물 — 등록부 기본값을 칸에 실제 값으로(PLAN 46-7 · 사용자가 고치면 됨).
|
||||
renderOptionFields();
|
||||
syncFacilityForm();
|
||||
if (addsAtOnce(type, optionInputs))
|
||||
return void finishAdd({ type, anchorM: chainageM, structures, commit, pick: this });
|
||||
// 임시 배치도 즉시 진행(A군).
|
||||
if (type.managed_by) commitTempPipe();
|
||||
syncButtons();
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/* =============================================================================
|
||||
* B05_Profile_UI_Structures_Panel_AddAt.ts
|
||||
* 종단 우클릭 → 종류 고름 = 「[추가]까지 끝난 상태」(PLAN 116-1) — 세 길(B05 종단 · B06 종단 ·
|
||||
* 3D)이 함께 쓰는 패널 `addAt` 의 끝맺음. 필수 빈칸이 없는 종류는 그 측점에 바로 추가하고
|
||||
* 새 항목을 고른 채로 둠 · 남는 종류는 폼만.
|
||||
* ========================================================================== */
|
||||
|
||||
import type { StructureInstance, StructureType } from "./B05_Profile_Api_Structures";
|
||||
import type { StructuresSection } from "./B05_Profile_UI_Structures_Panel_Types";
|
||||
|
||||
/** 바로 추가하지 않는 종류 — 노면공(겹침 확인창) · 세월교 · 물넘이포장(월류 높이가 유량 뒤 채워짐). */
|
||||
const FORM_ONLY = new Set(["pavement_concrete", "ford_bridge", "ford_pavement"]);
|
||||
|
||||
/** 우클릭 한 번으로 [추가]까지 끝낼 수 있는지 — [추가]가 막는 빈 필수 칸이 없어야 함. */
|
||||
export function addsAtOnce(
|
||||
type: StructureType,
|
||||
optionInputs: ReadonlyArray<{ required: boolean; isEmpty: () => boolean }>,
|
||||
): boolean {
|
||||
if (FORM_ONLY.has(type.type_id)) return false;
|
||||
return !optionInputs.some((entry) => entry.required && entry.isEmpty());
|
||||
}
|
||||
|
||||
/** [추가]를 대신 누르고 새 항목을 고름. [추가]가 거절하면(전길이 > 기준 등) 아무것도 안 들고
|
||||
* 그 칸에 포커스가 간 폼 그대로 남음 — false. */
|
||||
export async function finishAdd(ctx: {
|
||||
type: StructureType;
|
||||
anchorM: number;
|
||||
structures: StructureInstance[];
|
||||
commit: () => Promise<void>;
|
||||
/** 패널 — 바깥에서 고를 때와 같은 길(좌측 패널 폄 · 폼 · 목록 고름). */
|
||||
pick: Pick<StructuresSection, "selectById" | "selectPipeByChainage">;
|
||||
}): Promise<boolean> {
|
||||
if (ctx.type.managed_by) {
|
||||
// 관 지점 정본 — 배수유역 재계산은 종전 [추가] 그대로. B06 은 목록에 바로 들어 여기서 고르고,
|
||||
// B05 는 재계산 뒤 배수유역 패널이 새 관 고름을 다시 알려 폼이 열림.
|
||||
await ctx.commit();
|
||||
ctx.pick.selectPipeByChainage(ctx.anchorM);
|
||||
return true;
|
||||
}
|
||||
const before = new Set(ctx.structures.map((entry) => entry.structure_id));
|
||||
await ctx.commit(); // 목록 알림 → 페이지가 임시 id 를 붙여 되돌려 줌(`withLocalIds`)
|
||||
const added = ctx.structures.find(
|
||||
(entry) => !!entry.structure_id && !before.has(entry.structure_id),
|
||||
);
|
||||
if (!added?.structure_id) return false;
|
||||
ctx.pick.selectById(added.structure_id);
|
||||
return true;
|
||||
}
|
||||
@@ -36,7 +36,9 @@ export interface StructuresEventContext extends StructuresCommitContext {
|
||||
optionRow: HTMLElement;
|
||||
}
|
||||
|
||||
export function bindStructuresEvents(ctx: StructuresEventContext): void {
|
||||
export function bindStructuresEvents(ctx: StructuresEventContext): {
|
||||
startNew: (group: string, typeId?: string) => void;
|
||||
} {
|
||||
/** 새로 놓기(54-32) — 고름 · 측점 · 강조를 풀고 군(· 종류)만 남긴 빈 기본값 폼. */
|
||||
function startNew(group: string, typeId?: string): void {
|
||||
ctx.resetForm();
|
||||
@@ -223,4 +225,5 @@ export function bindStructuresEvents(ctx: StructuresEventContext): void {
|
||||
});
|
||||
|
||||
ctx.memoField.addEventListener("change", () => ctx.liveCommit());
|
||||
return { startNew }; // 우클릭 추가도 새로 놓기에서 시작(116-1)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user