Merge remote-tracking branch 'origin/dev' into sub_laptop_4
This commit is contained in:
@@ -262,7 +262,7 @@ export async function mountM01LogicLab(
|
||||
// 왼쪽 「전체」 + 구분 → 상세구분 거름 — 고르면 목록으로 돌아와 그 범위만
|
||||
filterHost.replaceChildren(
|
||||
side.filter({
|
||||
id: "로직시험|",
|
||||
id: "로직|",
|
||||
store: "m01.filter.로직시험",
|
||||
subs,
|
||||
total: list.total(),
|
||||
@@ -421,7 +421,7 @@ export async function mountM01LogicLab(
|
||||
],
|
||||
}),
|
||||
);
|
||||
side.labHost.replaceChildren(filterHost);
|
||||
side.logicHost.replaceChildren(filterHost);
|
||||
show(null);
|
||||
showLoadingOverlay();
|
||||
const openKeyOn = async (key: string): Promise<void> => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* =============================================================================
|
||||
* M01_MasterData_UI_LogicLab_Detail.ts
|
||||
* 「로직 개선 시험」 상세 화면 — 컨테이너 넷을 위에서 아래로
|
||||
* 「단가산출 로직」 상세 화면 — 컨테이너 넷을 위에서 아래로
|
||||
* ① 기본정보(정본은 읽기 전용 · 비고만 고침) ② 단가산출 상세(인력·자재·경비·그 밖 묶음 + 소계)
|
||||
* ③ 텍스트 수식(자리 — `_LogicLab_Formula.ts`) ④ 시험 계산(입력값 + 결과값 — `Logic_Calc` 그대로)
|
||||
* 호표 줄을 누르면 그 줄이 쓰는 자료 모달(`_LogicLab_Modal.ts`)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* =============================================================================
|
||||
* M01_MasterData_UI_LogicLab_New.ts
|
||||
* 「로직 개선 시험」 — 식으로 새 로직 만들기 (PLAN 3-3 · 계약 `_화면_계약.md` 7장)
|
||||
* 「단가산출 로직」 — 식으로 새 로직 만들기 (PLAN 3-3 · 계약 `_화면_계약.md` 7장)
|
||||
* ① 식을 줄로 적음 ② [분석] → 변수 표에서 변수마다 무엇인지·단위·비목을 고름
|
||||
* ③ 이름·결과 단위 ④ 시험 계산으로 값을 보고 저장(자체 로직 · 키 GX)
|
||||
* 검사에 걸린 것은 그 줄·자리를 짚어 쉬운 말로 보임 — 서버 글 그대로(`문제`)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* =============================================================================
|
||||
* M01_MasterData_UI_LogicLab_Text.ts
|
||||
* 「로직 개선 시험」 컨테이너 글자 — [한국어, 영어]
|
||||
* 「단가산출 로직」 컨테이너 글자 — [한국어, 영어]
|
||||
* ========================================================================== */
|
||||
|
||||
import { currentLanguageIndex } from "@ui/ui_template_locale";
|
||||
@@ -53,7 +53,7 @@ const TEXT = {
|
||||
Pill_Table: ["표", "Table"],
|
||||
Pill_Logic: ["로직", "Logic"],
|
||||
Pill_Go: ["마스터 화면에서 보기", "Open in master"],
|
||||
Pill_Back: ["← 로직 개선 시험으로 돌아가기", "← Back to logic lab"],
|
||||
Pill_Back: ["← 단가산출 로직으로 돌아가기", "← Back to unit-price logic"],
|
||||
Pill_NoPick: [
|
||||
"고르기 조건에 맞는 마스터 줄이 없음 — 단가를 못 찾음",
|
||||
"No master row matches the pick conditions",
|
||||
|
||||
@@ -17,7 +17,6 @@ const TEXT = {
|
||||
List_New: ["새것", "New"],
|
||||
List_Deleted: ["지움", "Deleted"],
|
||||
Bar_Back: ["← 로직 목록", "← Logics"],
|
||||
Bar_New: ["로직 새로 만들기", "New logic"],
|
||||
Bar_Delete: ["로직 지우기", "Delete logic"],
|
||||
Bar_Save: ["저장", "Save"],
|
||||
Bar_Discard: ["고친 것 버리기", "Discard edits"],
|
||||
@@ -85,7 +84,7 @@ const TEXT = {
|
||||
Save_Failed: ["저장 못 함", "Save failed"],
|
||||
Save_Nothing: ["고친 것 없음", "Nothing to save"],
|
||||
Load_Failed: ["불러오지 못함", "Load failed"],
|
||||
Lab_Title: ["로직 개선 시험", "Logic — improvement lab"],
|
||||
Lab_Title: ["단가산출 로직", "Unit-price logic"],
|
||||
Loading: ["불러오는 중", "Loading"],
|
||||
Confirm_Delete: [
|
||||
"로직 「{v}」 을 지울까요? [저장] 때 파일에서 빠짐",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* =============================================================================
|
||||
* M01_MasterData_UI_Page.ts
|
||||
* 마스터 요소 화면 — 좌측 도킹 패널(컨테이너: 인력·재료·기계·소요량·계수·환율·요율·단가산출 로직·일위대가 조합·로직 테스트)
|
||||
* 마스터 요소 화면 — 좌측 도킹 패널(컨테이너: 인력·재료·기계·소요량·계수·환율·요율·단가산출 로직·일위대가 조합)
|
||||
* / 우측 요소 표 · 표 목록 · 로직 편집
|
||||
*
|
||||
* 시스템 관리자만. 고친 것은 초안(sessionStorage)에 쌓이고 [저장] 한 번에 서버로 —
|
||||
@@ -37,7 +37,7 @@ import {
|
||||
import { loadTable } from "./M01_MasterData_UI_Logic_Note";
|
||||
import { tl } from "./M01_MasterData_UI_LogicLab_Text";
|
||||
import { renderTables } from "./M01_MasterData_UI_Tables";
|
||||
import type { LogicHandle } from "./M01_MasterData_UI_Logic_Page";
|
||||
import type { LogicHandle } from "./M01_MasterData_UI_LogicLab";
|
||||
import type { ComboHandle } from "./M01_MasterData_UI_Combo";
|
||||
import "./M01_MasterData_UI_Style.css";
|
||||
|
||||
@@ -59,7 +59,6 @@ function buildPage(): HTMLElement {
|
||||
let query = "";
|
||||
let dispose = (): void => {};
|
||||
let logicMounted = false;
|
||||
let labMounted = false;
|
||||
let comboHandle: ComboHandle | null = null;
|
||||
|
||||
/* --- 우측: 머리(제목·찾기·저장) + 알림 + 본문 --- */
|
||||
@@ -76,7 +75,6 @@ function buildPage(): HTMLElement {
|
||||
children: [title, searchField.root, summary, drop, save],
|
||||
});
|
||||
const logicHost = el("div", { className: "m01-master__logic", attrs: { hidden: "" } });
|
||||
const labHost = el("div", { className: "m01-master__logic", attrs: { hidden: "" } });
|
||||
const comboHost = el("div", { className: "m01-master__logic", attrs: { hidden: "" } });
|
||||
const elementView = el("div", {
|
||||
className: "m01-master__elements",
|
||||
@@ -100,9 +98,8 @@ function buildPage(): HTMLElement {
|
||||
onDraftChange(refreshBar);
|
||||
refreshBar();
|
||||
|
||||
const showMode = (mode: "elements" | "logic" | "lab" | "combo"): void => {
|
||||
const showMode = (mode: "elements" | "logic" | "combo"): void => {
|
||||
logicHost.hidden = mode !== "logic";
|
||||
labHost.hidden = mode !== "lab";
|
||||
comboHost.hidden = mode !== "combo";
|
||||
elementView.hidden = mode !== "elements";
|
||||
};
|
||||
@@ -190,7 +187,7 @@ function buildPage(): HTMLElement {
|
||||
|
||||
let logicHandle: LogicHandle | null = null;
|
||||
|
||||
/** 로직 탭으로 전환 — `key` 가 있으면 그 로직을 바로 엶. */
|
||||
/** 「단가산출 로직」 탭으로 전환 — `key` 가 있으면 그 로직을 바로 엶. */
|
||||
const openLogicTab = (key?: string): void => {
|
||||
if (key) setPendingLogicKey(key);
|
||||
dispose();
|
||||
@@ -203,23 +200,12 @@ function buildPage(): HTMLElement {
|
||||
return;
|
||||
}
|
||||
logicMounted = true;
|
||||
void import("./M01_MasterData_UI_Logic_Page").then(async (m) => {
|
||||
void import("./M01_MasterData_UI_LogicLab").then(async (m) => {
|
||||
const pending = takePendingLogicKey();
|
||||
logicHandle = await m.mountM01Logic(logicHost, side, pending ?? undefined);
|
||||
logicHandle = await m.mountM01LogicLab(logicHost, side, pending ?? undefined);
|
||||
});
|
||||
};
|
||||
|
||||
/** 「로직 개선 시험」 — 정본 로직 화면의 복사본(개선은 여기서만) */
|
||||
const openLabTab = (): void => {
|
||||
dispose();
|
||||
dispose = (): void => {};
|
||||
current = null;
|
||||
showMode("lab");
|
||||
if (labMounted) return;
|
||||
labMounted = true;
|
||||
void import("./M01_MasterData_UI_LogicLab").then((m) => m.mountM01LogicLab(labHost, side));
|
||||
};
|
||||
|
||||
/** 「일위대가 조합」 — 목록을 새로 받아 그림 · 로직 줄을 누르면 단가산출 로직 탭으로 */
|
||||
const openComboTab = (): void => {
|
||||
dispose();
|
||||
@@ -236,7 +222,7 @@ function buildPage(): HTMLElement {
|
||||
});
|
||||
};
|
||||
|
||||
/** 알약 → 마스터 화면 — 찾기 글을 그 키로 두고 열고, 알림줄에 「시험으로 돌아가기」를 둠 */
|
||||
/** 알약 → 마스터 화면 — 찾기 글을 그 키로 두고 열고, 알림줄에 「단가산출 로직으로 돌아가기」를 둠 */
|
||||
const jump = async (target: MasterJump): Promise<void> => {
|
||||
let group = target.kind === "element" ? target.group : "";
|
||||
let file: FileInfo | undefined;
|
||||
@@ -258,7 +244,7 @@ function buildPage(): HTMLElement {
|
||||
const back = createButton({ label: tl("Pill_Back"), variant: "ghost" });
|
||||
back.addEventListener("click", () => {
|
||||
showNotice([]);
|
||||
openLabTab();
|
||||
openLogicTab();
|
||||
});
|
||||
showNotice([back]);
|
||||
if (target.kind === "table") {
|
||||
@@ -276,7 +262,7 @@ function buildPage(): HTMLElement {
|
||||
setMasterJump((target) => void jump(target));
|
||||
|
||||
/* --- 좌측: 컨테이너 --- */
|
||||
const side = buildSide(openFile, () => openLogicTab(), openLabTab, openComboTab);
|
||||
const side = buildSide(openFile, () => openLogicTab(), openComboTab);
|
||||
|
||||
const layout = el("div", { className: "ui-workflow-layout m01-master" });
|
||||
const main = el("main", {
|
||||
@@ -284,7 +270,7 @@ function buildPage(): HTMLElement {
|
||||
children: [
|
||||
el("div", {
|
||||
className: "m01-master__panel",
|
||||
children: [elementView, logicHost, labHost, comboHost],
|
||||
children: [elementView, logicHost, comboHost],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -59,7 +59,7 @@ export function takePendingLogicKey(): string | null {
|
||||
}
|
||||
}
|
||||
|
||||
/** 「로직 개선 시험」 알약 → 마스터 화면 — 표(키) 또는 요소(그룹 · 키 · 파일) */
|
||||
/** 「단가산출 로직」 알약 → 마스터 화면 — 표(키) 또는 요소(그룹 · 키 · 파일) */
|
||||
export type MasterJump =
|
||||
{ kind: "table"; key: string } | { kind: "element"; group: string; ref: string; file?: string };
|
||||
|
||||
@@ -88,8 +88,6 @@ export interface SideHandle {
|
||||
logicHost: HTMLElement;
|
||||
/** 일위대가 조합 컨테이너 안(구분 · 상세구분 거름이 들어갈 자리) */
|
||||
comboHost: HTMLElement;
|
||||
/** 「로직 개선 시험」 컨테이너 안 */
|
||||
labHost: HTMLElement;
|
||||
/** 그룹의 파일 판본을 다시 받음(저장 뒤) — 돌려받는 것 = 새 목록 */
|
||||
refresh: (group: string) => Promise<FileInfo[]>;
|
||||
/** 그룹의 파일 목록(이미 받은 것) */
|
||||
@@ -147,13 +145,11 @@ const LEAF: Group[] = ["환율", "요율"];
|
||||
/** 거름이 있는 컨테이너 — 펼치면 「전체」(또는 닫기 전 거름) 이 바로 열림 */
|
||||
const FILTERED: Group[] = ["인력", "기계", "소요량", "계수"];
|
||||
const LOGIC_ID = "로직|";
|
||||
const LAB_ID = "로직시험|";
|
||||
const COMBO_ID = "조합|";
|
||||
|
||||
export function buildSide(
|
||||
onOpen: (pick: Pick) => void,
|
||||
onLogic: () => void,
|
||||
onLab: () => void,
|
||||
onCombo: () => void = () => {},
|
||||
): SideHandle {
|
||||
const lists = new Map<Group, FileInfo[]>();
|
||||
@@ -447,7 +443,7 @@ ${first.file}`
|
||||
});
|
||||
|
||||
const logicHost = el("div", { className: "m01-side__items" });
|
||||
const logic = section(L("M01_GroupLogic"), logicHost);
|
||||
const logic = section(tx("Lab_Title"), logicHost);
|
||||
logic.querySelector(".ui-collapsible__title")?.addEventListener("click", () => {
|
||||
if (!logic.classList.contains("is-collapsed")) return; // 닫을 때는 그대로 둠
|
||||
setActive(buttons.has(LOGIC_ID) ? LOGIC_ID : null);
|
||||
@@ -462,15 +458,7 @@ ${first.file}`
|
||||
onCombo();
|
||||
});
|
||||
|
||||
const labHost = el("div", { className: "m01-side__items" });
|
||||
const lab = section(tx("Lab_Title"), labHost);
|
||||
lab.querySelector(".ui-collapsible__title")?.addEventListener("click", () => {
|
||||
if (!lab.classList.contains("is-collapsed")) return;
|
||||
setActive(buttons.has(LAB_ID) ? LAB_ID : null);
|
||||
onLab();
|
||||
});
|
||||
|
||||
const root = el("div", { className: "m01-side", children: [...groups, logic, combo, lab] });
|
||||
const root = el("div", { className: "m01-side", children: [...groups, logic, combo] });
|
||||
attachCollapsible(root);
|
||||
void Promise.all(GROUPS.map(refresh)).catch((error) =>
|
||||
showToast(error instanceof Error ? error.message : L("M01_LoadFailed"), "error"),
|
||||
@@ -479,5 +467,5 @@ ${first.file}`
|
||||
onPicked = fn;
|
||||
};
|
||||
const files = (group: string): FileInfo[] => lists.get(group as Group) ?? [];
|
||||
return { root, logicHost, comboHost, labHost, refresh, files, setActive, setOnPicked, filter };
|
||||
return { root, logicHost, comboHost, refresh, files, setActive, setOnPicked, filter };
|
||||
}
|
||||
|
||||
+21
-9
@@ -1,5 +1,12 @@
|
||||
/* =============================================================================
|
||||
* M01_MasterData_UI_Logic_Page.ts
|
||||
* M01_MasterData_UI_Logic_Page.ts (은퇴 — PLAN 7-1 로 「단가산출 로직」 컨테이너를
|
||||
* `M01_MasterData_UI_LogicLab.ts` 하나로 합치며 old_code/ 로 옮김 · 빌드에서 빠짐 · 지우지 않고 자료로만 둠)
|
||||
*
|
||||
* 옛 「단가산출 로직」 컨테이너 — 정본 GC·GF 로직을 화면에서 바로 고쳐 저장 · 정본 파일에 빈 줄 더하는
|
||||
* 두 길이 여기에만 있었음(새 컨테이너는 자체 GX 로직만 고침) — 사용자 확정으로 버림.
|
||||
* 경로만 옮김 · import 는 위 M01_MasterData/ 의 그대로 남은 파일을 가리키도록 고침(통째 복사 아님).
|
||||
* 분석 = resources/master_data/ref/_분석_로직컨테이너_통합.md.
|
||||
*
|
||||
* 관리자 화면 — 로직 칸. 가운데 단가산출 상세(호표) 고치기 / 오른쪽 시험 계산
|
||||
* 로직 목록(원문·장 고르기 · 찾기 · 막힘 거름)은 왼쪽 패널 「단가산출 로직」 컨테이너(`listHost`) 안
|
||||
*
|
||||
@@ -29,14 +36,19 @@ import {
|
||||
type LogicRow,
|
||||
type LogicSummary,
|
||||
type SaveFile,
|
||||
} from "./M01_MasterData_UI_Logic_Api";
|
||||
import { buildCalc } from "./M01_MasterData_UI_Logic_Calc";
|
||||
import { buildEditor } from "./M01_MasterData_UI_Logic_Edit";
|
||||
import { buildList, logicId, type ListItem, type ListMark } from "./M01_MasterData_UI_Logic_List";
|
||||
import { openPicker } from "./M01_MasterData_UI_Logic_Pick";
|
||||
import type { SideHandle } from "./M01_MasterData_UI_Side";
|
||||
import { tx } from "./M01_MasterData_UI_Logic_Text";
|
||||
import "./M01_MasterData_UI_Logic_Style.css";
|
||||
} from "../../M01_MasterData/M01_MasterData_UI_Logic_Api";
|
||||
import { buildCalc } from "../../M01_MasterData/M01_MasterData_UI_Logic_Calc";
|
||||
import { buildEditor } from "../../M01_MasterData/M01_MasterData_UI_Logic_Edit";
|
||||
import {
|
||||
buildList,
|
||||
logicId,
|
||||
type ListItem,
|
||||
type ListMark,
|
||||
} from "../../M01_MasterData/M01_MasterData_UI_Logic_List";
|
||||
import { openPicker } from "../../M01_MasterData/M01_MasterData_UI_Logic_Pick";
|
||||
import type { SideHandle } from "../../M01_MasterData/M01_MasterData_UI_Side";
|
||||
import { tx } from "../../M01_MasterData/M01_MasterData_UI_Logic_Text";
|
||||
import "../../M01_MasterData/M01_MasterData_UI_Logic_Style.css";
|
||||
|
||||
/** 저장 안 한 로직 하나 — origKey null = 새 로직 · row null = 지움 */
|
||||
interface Draft {
|
||||
Reference in New Issue
Block a user