diff --git a/B05_Profile/B05_Profile_UI_Profile_Structures.ts b/B05_Profile/B05_Profile_UI_Profile_Structures.ts index eef902955..a9d6ca393 100644 --- a/B05_Profile/B05_Profile_UI_Profile_Structures.ts +++ b/B05_Profile/B05_Profile_UI_Profile_Structures.ts @@ -17,7 +17,7 @@ import { } from "./B05_Profile_UI_IrregularStations"; import { structureAnchorM, type StructureInstance } from "./B05_Profile_Api_Structures"; import { GROUP_LABELS } from "./B05_Profile_UI_Structures_Panel"; -import { HIDDEN_PICK_GROUPS } from "./B05_Profile_UI_Structures_Panel_Types"; +import { isPickHidden } from "./B05_Profile_UI_Structures_Panel_Types"; /** 우클릭 메뉴용 최소 타입 정보 — 사이드 「구조물 배치」 종류 목록과 같은 원천. */ export interface StructureMenuType { @@ -33,12 +33,11 @@ export function structureGroupMenuItems( types: ReadonlyArray, onPick: (typeId: string) => void, ): MapContextMenuItem[] { - const groups = [...new Set(types.map((type) => type.group))].filter( - (group) => !HIDDEN_PICK_GROUPS.has(group), - ); + const pickable = types.filter((type) => !isPickHidden(type)); + const groups = [...new Set(pickable.map((type) => type.group))]; return groups.map((group) => ({ label: GROUP_LABELS[group] ?? group, - children: types + children: pickable .filter((type) => type.group === group) .map((type): [string, () => void] => [type.name, () => onPick(type.type_id)]), })); diff --git a/B05_Profile/B05_Profile_UI_Structures_Panel.ts b/B05_Profile/B05_Profile_UI_Structures_Panel.ts index aec944f83..2e2f95114 100644 --- a/B05_Profile/B05_Profile_UI_Structures_Panel.ts +++ b/B05_Profile/B05_Profile_UI_Structures_Panel.ts @@ -56,7 +56,7 @@ import { DEFAULT_INTERVAL_LENGTH_M, groupOptions, hasComputedRange, - pickOption, + typeOptions, readBeforeOption, readLengthOption, type PipeFacilityItem, @@ -347,10 +347,7 @@ export function createStructuresSection( function syncTypeOptions(keepTypeId?: string): void { const group = groupSelect.value; const candidates = group ? types.filter((t) => t.group === group && pickable(t)) : []; - typeSelect.replaceChildren( - new Option("— 선택 —", ""), - ...candidates.map((type) => pickOption(type.name, type.type_id, !canPick(type))), - ); + typeSelect.replaceChildren(new Option("— 선택 —", ""), ...typeOptions(candidates, canPick)); typeSelect.value = keepTypeId && candidates.some((type) => type.type_id === keepTypeId) ? keepTypeId : ""; syncPlacementFields(); diff --git a/B05_Profile/B05_Profile_UI_Structures_Panel_Types.ts b/B05_Profile/B05_Profile_UI_Structures_Panel_Types.ts index e667ce5ae..fec141a06 100644 --- a/B05_Profile/B05_Profile_UI_Structures_Panel_Types.ts +++ b/B05_Profile/B05_Profile_UI_Structures_Panel_Types.ts @@ -38,6 +38,18 @@ export const GROUP_LABELS: Record = { * 옛 값 · 도면 · 집계는 그대로이고 데이터도 지우지 않는다. */ export const HIDDEN_PICK_GROUPS: ReadonlySet = new Set(["B", "D"]); +/** 고르기 목록에서 뺄 종류 — 사면안정은 흙막이 · 옹벽 · 소단만(54-31). 옛 값은 그대로. */ +export const HIDDEN_PICK_TYPES: ReadonlySet = new Set([ + "masonry_wet", + "masonry_dry", + "boulder_masonry", +]); + +/** 새로 놓을 때 고르기 목록에서 가릴 종류인가 — 뺄 군이거나 뺄 종류. */ +export function isPickHidden(type: { group: string; type_id: string }): boolean { + return HIDDEN_PICK_GROUPS.has(type.group) || HIDDEN_PICK_TYPES.has(type.type_id); +} + /** 고르기 목록 항목 — 가릴 항목은 가림(옛 항목을 열 때는 값으로 그대로 고를 수 있음). */ export function pickOption(text: string, value: string, hidden: boolean): HTMLOptionElement { const option = new Option(text, value); @@ -56,11 +68,19 @@ export function groupOptions( pickOption( name ?? GROUP_LABELS[g] ?? g, g, - HIDDEN_PICK_GROUPS.has(g) || !types.some((t) => t.group === g && pick(t)), + !types.some((t) => t.group === g && pick(t) && !isPickHidden(t)), ), ); } +/** 종류 드롭다운 항목들 — 고를 수 없거나 뺄 종류는 가림. */ +export function typeOptions( + types: StructureType[], + pick: (type: StructureType) => boolean, +): HTMLOptionElement[] { + return types.map((t) => pickOption(t.name, t.type_id, !pick(t) || isPickHidden(t))); +} + /** 구간형 신규 추가 시 기본 구간 길이(m). 사용자가 종점을 바로 고칠 수 있게 짧게 잡는다. */ export const DEFAULT_INTERVAL_LENGTH_M = 15;