- B05 Drainage_Saved 새 파일 — 저장분 받기를 패널 밖으로 뗌(Panel 700 → 688 줄) · 떠 있는 받기는 같이 씀 · 화면이 마지막 저장분 그대로면 초안 버림은 GET 없이 그 답을 다시 올림 · 뒤이어 온 reload 가 밀어내면 그 답을 기다림(낡음 남지 않음) - 원인 — Ctrl+Z 한 번에 관 자리 되돌림(setPipeChainages) · 시설 따라감(reload) · 묶음 초안 버림(backToSaved) 셋이 저장분을 따로 받음 - 관 자리 되돌림 건너뜀 조건 — 요청 몸통만 견주던 것을 「화면이 저장분 답 그대로」까지 봄(지금 노선 [업데이트] 답이 오른 뒤엔 다시 받음) - 지킴 시험 test_520_7 — 세 부름 = GET 한 번 · 초안 버림 먼저여도 올림 · 저장분 그대로면 GET 없음 · 세션 관 초안은 세부 유역 계산 - 낡은 시험 고침 — test_298 · test_472_d · test_b05_structures_form_summary 가 패널 원문에서 찾던 저장분 받기 줄이 새 파일로 옮겨짐 - 이음매 대조(tmp 일회) — primary-region 길 대 저장 노선 [업데이트] 길 네 프로젝트 도로로 오는 셀 · road_slot · 관별 면적 차이 0 · 초안 2.2~2.3 s · 저장 노선 2.1~2.6 s · Ctrl+Z GET 1 · 낡음 꺼짐 249~258 ms Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
86 lines
4.0 KiB
TypeScript
86 lines
4.0 KiB
TypeScript
/* =============================================================================
|
|
* B05_Profile_UI_Drainage_Saved.ts
|
|
* 저장 배수유역 다시 받기(열 때 · 초안 버림 · 되돌리기) — 패널 본체가 700줄이라 나눔(520-7).
|
|
*
|
|
* - 세션 관 초안이 있으면 그 관 목록으로 세부유역(저장 안 함) · 없으면 저장분 GET.
|
|
* - 되돌리기 한 번에 셋(관 자리 되돌림 · 시설 따라감 `reload` · 묶음 초안 버림)이 같이 부름 —
|
|
* 떠 있는 받기가 있으면 그 답을 같이 씀(모두 같은 「올렸나」를 받음).
|
|
* - 마지막 저장분 답 · 그 답을 실은 뒤 요청 몸통 — 화면이 그 답 그대로(뒤에 다른 답이 안 올랐고 관
|
|
* 목록 같음)면 관 자리 되돌림은 건너뜀(472 덧) · 초안 버림(`back`)은 그 답을 다시 올림(GET 없음 ·
|
|
* 낡음 표시만 다시 셈). `reload` 는 늘 받음(B06 관 쓰기 · [확정] 뒤).
|
|
* ========================================================================== */
|
|
|
|
import {
|
|
computeDetailBasins,
|
|
fetchDetailPipePoints,
|
|
type DetailBasinResponse,
|
|
type DetailPipeInput,
|
|
} from "../B04_PreProcess/B04_PreProcess_Api_Fetch";
|
|
import { readPendingPipes } from "./B05_Profile_Api_Pipes_Draft";
|
|
import type { DetailRunner } from "./B05_Profile_UI_Drainage_Run";
|
|
|
|
export interface SavedLoader {
|
|
/** 저장분(세션 초안이 있으면 그 관 목록) 받기 — 답을 화면에 올렸으면 true. */
|
|
run(quiet?: boolean): Promise<boolean>;
|
|
/** 초안 버림 — 화면이 마지막 저장분 그대로면 그 답을 다시 올림(GET 없음) · 아니면 `run`. */
|
|
back(): Promise<boolean>;
|
|
/** 답이 화면에 오른 뒤 — 저장분 답이면 그때 요청 몸통을 적어 둠 · 아니면 「화면 ≠ 저장분」. */
|
|
applied(response: DetailBasinResponse): void;
|
|
/** 화면이 마지막 저장분 답 그대로이고 지금 요청 몸통도 같은가. */
|
|
matches(): boolean;
|
|
/** 프로젝트가 바뀜 — 옛 저장분 잊음. */
|
|
reset(): void;
|
|
}
|
|
|
|
export function createSavedLoader(
|
|
runner: DetailRunner,
|
|
pipeRequest: () => DetailPipeInput[],
|
|
): SavedLoader {
|
|
let saved: { response: DetailBasinResponse; request: string | null } | null = null;
|
|
let inflight: Promise<boolean> | null = null;
|
|
/** 마지막으로 화면에 오른 답이 `saved.response` 인가. */
|
|
let showing = false;
|
|
|
|
const load = (projectId: string): Promise<DetailBasinResponse> => {
|
|
const pending = readPendingPipes(projectId);
|
|
return pending !== null // 빈 목록 = 다 지움(관 0개 · 312) — 저장분으로 안 넘어감
|
|
? computeDetailBasins(projectId, pending)
|
|
: fetchDetailPipePoints(projectId).then(
|
|
(response) => ((saved = { response, request: null }), response),
|
|
);
|
|
};
|
|
|
|
const matches = (): boolean =>
|
|
showing && !!saved && JSON.stringify(pipeRequest()) === saved.request;
|
|
|
|
const run = (quiet = false): Promise<boolean> => {
|
|
const projectId = runner.projectId();
|
|
if (!projectId) return Promise.resolve(false);
|
|
// ponytail: 떠 있는 동안 온 부름은 그 답을 같이 — 그 사이 서버 쓰기(B06 관 쓰기 뒤 reload)는
|
|
// 다음 부름까지 안 보임. 잦아지면 쓰기 뒤 부름만 새로 받게 표시를 넘김.
|
|
inflight ??= runner.run(() => load(projectId), quiet).finally(() => (inflight = null));
|
|
return inflight;
|
|
};
|
|
|
|
return {
|
|
run,
|
|
back() {
|
|
if (inflight || !matches()) return run(true);
|
|
const response = saved!.response;
|
|
// 뒤이어 온 받기(`reload`)가 이 답을 밀어내면 그 답을 기다림 — 「안 올림」으로 낡음이 남지 않게.
|
|
return runner
|
|
.run(() => Promise.resolve(response), true)
|
|
.then((applied) => applied || (inflight ?? Promise.resolve(false)));
|
|
},
|
|
applied(response) {
|
|
showing = saved?.response === response;
|
|
if (showing) saved!.request = JSON.stringify(pipeRequest());
|
|
},
|
|
matches,
|
|
reset() {
|
|
saved = null;
|
|
showing = false;
|
|
},
|
|
};
|
|
}
|