Merge remote-tracking branch 'origin/sub_laptop_8' into main_laptop_1
This commit is contained in:
@@ -313,15 +313,14 @@ export function createStructuresBridge(deps: StructuresBridgeDeps) {
|
||||
async function loadStructures(): Promise<void> {
|
||||
try {
|
||||
// 레지스트리는 **한 번만** 받고 쓰는 자리에 따라 나눈다(2026-09-07).
|
||||
// · 추가 메뉴 — 켜진 종류만(B05 는 종전대로 여섯 군).
|
||||
// · 알약 레인·군 판정 — **전부**. B06 에서 넣은 B군(측구·맹암거 등)은 레지스트리에서
|
||||
// 꺼져 있는데, 켜진 것만 주면 이름·색·군을 못 찾아 종단에 「?」 회색 알약으로 뜬다.
|
||||
// · 고르기 목록 — 켜진 종류만(B05 는 종전대로 여섯 군).
|
||||
// · 목록 이름 · 폼 · 알약 레인 · 군 판정 — **전부**. B06 에서 넣은 B군(측구·맹암거 등)은
|
||||
// 레지스트리에서 꺼져 있는데, 켜진 것만 주면 이름을 못 찾아 영문 키 · 「?」 알약으로 뜬다.
|
||||
const [allTypes, stored] = await Promise.all([
|
||||
fetchStructureTypes(true),
|
||||
fetchStructures(deps.projectId),
|
||||
]);
|
||||
const menuTypes = allTypes.filter((type) => type.enabled);
|
||||
deps.panel().structures.setTypes(menuTypes);
|
||||
deps.panel().structures.setTypes(allTypes, (type) => type.enabled);
|
||||
deps.profilePanel().setStructureTypes(allTypes);
|
||||
// A군 판정에 쓸 타입 정보 — 횡단배수만 그래프 세로선·틸팅 대상이다.
|
||||
structureTypeMap = new Map(
|
||||
|
||||
@@ -53,9 +53,9 @@ export { GROUP_LABELS } from "./B05_Profile_UI_Structures_Panel_Types";
|
||||
export type { PipeFacilityItem, StructuresSection } from "./B05_Profile_UI_Structures_Panel_Types";
|
||||
import {
|
||||
DEFAULT_INTERVAL_LENGTH_M,
|
||||
GROUP_LABELS,
|
||||
groupOption,
|
||||
groupOptions,
|
||||
hasComputedRange,
|
||||
pickOption,
|
||||
readBeforeOption,
|
||||
readLengthOption,
|
||||
type PipeFacilityItem,
|
||||
@@ -165,6 +165,7 @@ export function createStructuresSection(
|
||||
}
|
||||
|
||||
let types: StructureType[] = [];
|
||||
let canPick: (type: StructureType) => boolean = () => true;
|
||||
// 배열 자체를 바꾸지 않는다(조각들이 참조로 들고 있음) — 내용만 갈아끼운다.
|
||||
const structures: StructureInstance[] = [];
|
||||
let pipeFacilities: PipeFacilityItem[] = [];
|
||||
@@ -348,7 +349,7 @@ export function createStructuresSection(
|
||||
const candidates = group ? types.filter((t) => t.group === group && pickable(t)) : [];
|
||||
typeSelect.replaceChildren(
|
||||
new Option("— 선택 —", ""),
|
||||
...candidates.map((type) => new Option(type.name, type.type_id)),
|
||||
...candidates.map((type) => pickOption(type.name, type.type_id, !canPick(type))),
|
||||
);
|
||||
typeSelect.value =
|
||||
keepTypeId && candidates.some((type) => type.type_id === keepTypeId) ? keepTypeId : "";
|
||||
@@ -539,14 +540,11 @@ export function createStructuresSection(
|
||||
facility: facilityOptions,
|
||||
listRoot: list,
|
||||
hasSelection: () => editingId !== null || selectedPipeChainage !== null,
|
||||
setTypes(next) {
|
||||
setTypes(next, pick = () => true) {
|
||||
types = next;
|
||||
const groups = new Map(next.map((t) => [t.group, t.group_name] as const));
|
||||
// 첫 항목은 빈칸 — 진입·리셋 상태에서 군·종류를 강제로 고르게 두지 않는다. 이름은 정의(48) 먼저.
|
||||
groupSelect.replaceChildren(
|
||||
new Option("— 선택 —", ""),
|
||||
...[...groups].map(([g, name]) => groupOption(g, name ?? GROUP_LABELS[g] ?? g)),
|
||||
);
|
||||
canPick = pick;
|
||||
// 첫 항목은 빈칸 — 진입·리셋 상태에서 군·종류를 강제로 고르게 두지 않는다.
|
||||
groupSelect.replaceChildren(new Option("— 선택 —", ""), ...groupOptions(next, pick));
|
||||
groupSelect.value = "";
|
||||
syncTypeOptions();
|
||||
},
|
||||
|
||||
@@ -38,14 +38,29 @@ export const GROUP_LABELS: Record<string, string> = {
|
||||
* 옛 값 · 도면 · 집계는 그대로이고 데이터도 지우지 않는다. */
|
||||
export const HIDDEN_PICK_GROUPS: ReadonlySet<string> = new Set(["B", "D"]);
|
||||
|
||||
/** 군 드롭다운 항목 — 뺄 군은 가림(옛 항목을 열 때는 값으로 그대로 고를 수 있음). */
|
||||
export function groupOption(group: string, name: string): HTMLOptionElement {
|
||||
const option = new Option(name, group);
|
||||
option.hidden = HIDDEN_PICK_GROUPS.has(group);
|
||||
if (option.hidden) option.dataset.pickHidden = ""; // 정의 폼의 「가림 풀기」가 건드리지 않게
|
||||
/** 고르기 목록 항목 — 가릴 항목은 가림(옛 항목을 열 때는 값으로 그대로 고를 수 있음). */
|
||||
export function pickOption(text: string, value: string, hidden: boolean): HTMLOptionElement {
|
||||
const option = new Option(text, value);
|
||||
option.hidden = hidden;
|
||||
if (hidden) option.dataset.pickHidden = ""; // 정의 폼의 「가림 풀기」가 건드리지 않게
|
||||
return option;
|
||||
}
|
||||
|
||||
/** 군 드롭다운 항목들 — 이름은 정의(48) 먼저 · 뺄 군과 고를 종류가 없는 군은 가림. */
|
||||
export function groupOptions(
|
||||
types: StructureType[],
|
||||
pick: (type: StructureType) => boolean,
|
||||
): HTMLOptionElement[] {
|
||||
const groups = new Map(types.map((t) => [t.group, t.group_name] as const));
|
||||
return [...groups].map(([g, name]) =>
|
||||
pickOption(
|
||||
name ?? GROUP_LABELS[g] ?? g,
|
||||
g,
|
||||
HIDDEN_PICK_GROUPS.has(g) || !types.some((t) => t.group === g && pick(t)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/** 구간형 신규 추가 시 기본 구간 길이(m). 사용자가 종점을 바로 고칠 수 있게 짧게 잡는다. */
|
||||
export const DEFAULT_INTERVAL_LENGTH_M = 15;
|
||||
|
||||
@@ -95,8 +110,9 @@ export interface StructuresSection {
|
||||
/** 배치된 구조물 목록(<ul>) — 섹션 본문이 아니라 사이드 하단 고정 영역에 붙인다
|
||||
* (2026-08-18 사용자 지시: 폼 길이에 밀려 목록이 화면 밖으로 나가던 문제). */
|
||||
listRoot: HTMLElement;
|
||||
/** 서버에서 받은 타입 목록을 채운다(최초 1회). */
|
||||
setTypes: (types: StructureType[]) => void;
|
||||
/** 서버에서 받은 타입 목록을 채운다(최초 1회). 이름·폼은 넘긴 종류 전부로 풀고,
|
||||
* 고르기 목록엔 `pick` 이 고른 종류만 보임(빼면 전부). */
|
||||
setTypes: (types: StructureType[], pick?: (type: StructureType) => boolean) => void;
|
||||
/** 서버 정본으로 목록을 교체한다(진입·복원·저장 후). */
|
||||
setStructures: (structures: StructureInstance[]) => void;
|
||||
getStructures: () => StructureInstance[];
|
||||
|
||||
Reference in New Issue
Block a user