Merge remote-tracking branches 'origin/sub_laptop_2' and 'origin/sub_laptop_3' into main_laptop_1
This commit is contained in:
@@ -23,6 +23,8 @@ import {
|
||||
type PickResult,
|
||||
} from "./M01_EasyCalc_Model";
|
||||
import { openEasyPick } from "./M01_EasyCalc_Pick";
|
||||
import { openEasyCond, readCond } from "./M01_EasyCalc_Cond";
|
||||
import { openEasyTable, readFinds } from "./M01_EasyCalc_Table";
|
||||
import "./M01_EasyCalc_Cards.css";
|
||||
|
||||
const TEXT = {
|
||||
@@ -60,6 +62,8 @@ const TEXT = {
|
||||
Auto: ["자동", "auto"],
|
||||
Locked: ["잠김", "Locked"],
|
||||
ToNumber: ["숫자로 바꾸기", "Make it a number"],
|
||||
ByTable: ["표 보고 고르기", "Choose from table"],
|
||||
ByCond: ["조건 보고 고치기", "Edit conditions"],
|
||||
ToNumber_Wait: ["계산이 끝난 뒤 가능", "Available after calculation"],
|
||||
ToNumber_Ask: [
|
||||
"자동 값을 그대로 숫자로 바꿈 · 이후 자동으로 달라지지 않음",
|
||||
@@ -92,7 +96,7 @@ interface Ctx {
|
||||
doc: EasyDoc;
|
||||
lines: Map<string, CalcLine>;
|
||||
readOnly: boolean;
|
||||
on: { change(doc: EasyDoc): void };
|
||||
on: { change(doc: EasyDoc): void; trial?(): Record<string, unknown> };
|
||||
/** 숫자 아님으로 친 글 — 다시 그려도 칸에 남김 */
|
||||
badText: Map<string, string>;
|
||||
}
|
||||
@@ -205,6 +209,22 @@ async function lockToNumber(ctx: Ctx, card: EasyCard, value: number): Promise<vo
|
||||
}
|
||||
}
|
||||
|
||||
/** 표 · 조건 창 — 답(새 식)이 있으면 그 카드 식만 바꿈 */
|
||||
async function editFormula(
|
||||
ctx: Ctx,
|
||||
card: EasyCard,
|
||||
open: typeof openEasyTable | typeof openEasyCond,
|
||||
): Promise<void> {
|
||||
if (picking) return;
|
||||
picking = true;
|
||||
try {
|
||||
const formula = await open(card, ctx.doc, ctx.on.trial?.());
|
||||
if (formula !== null) patchCard(ctx, card, { qtyFormula: formula });
|
||||
} finally {
|
||||
picking = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------ 칸 만들기 ------------------------------ */
|
||||
|
||||
const text = (cls: string, value: string): HTMLSpanElement =>
|
||||
@@ -414,6 +434,22 @@ function lockedNote(ctx: Ctx, card: EasyCard): HTMLElement {
|
||||
});
|
||||
if (!line) button.title = tc("ToNumber_Wait");
|
||||
note.push(button);
|
||||
const formula = card.qtyFormula;
|
||||
const tools: [boolean, keyof typeof TEXT, typeof openEasyTable | typeof openEasyCond][] = [
|
||||
[formula !== null && !!readFinds(formula)?.length, "ByTable", openEasyTable],
|
||||
[formula !== null && !!readCond(formula, ctx.doc.row), "ByCond", openEasyCond],
|
||||
];
|
||||
for (const [has, label, open] of tools) {
|
||||
if (has)
|
||||
note.push(
|
||||
createButton({
|
||||
label: tc(label),
|
||||
variant: "ghost",
|
||||
size: "sm",
|
||||
onClick: () => void editFormula(ctx, card, open),
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
return el("div", { className: "m01-easycards-locknote", children: note });
|
||||
}
|
||||
@@ -485,7 +521,7 @@ export function renderCards(
|
||||
host: HTMLElement,
|
||||
doc: EasyDoc,
|
||||
ans: CalcAnswer | null,
|
||||
on: { change(doc: EasyDoc): void },
|
||||
on: { change(doc: EasyDoc): void; trial?(): Record<string, unknown> },
|
||||
): void {
|
||||
const badText = badTexts.get(host) ?? new Map<string, string>();
|
||||
badTexts.set(host, badText);
|
||||
|
||||
@@ -15,12 +15,14 @@ import {
|
||||
} from "@ui/ui_template_elements";
|
||||
import { openModal } from "@ui/ui_template_modal";
|
||||
import { fetchPick, fetchSubs, type SubInfo } from "../M01_MasterData_Api_Fetch";
|
||||
import { fetchMaterials } from "../M01_MasterData_UI_Logic_Api";
|
||||
import { fetchMaterials, type ElementBrief } from "../M01_MasterData_UI_Logic_Api";
|
||||
import { listEasy, listMachines, machineElement, plainError } from "./M01_EasyCalc_Api";
|
||||
import type { PickResult } from "./M01_EasyCalc_Model";
|
||||
import "./M01_EasyCalc_Pick.css";
|
||||
|
||||
type Kind = PickResult["kind"];
|
||||
/** 후보 줄 — 서버는 구분 · 상세구분도 주지만 ElementBrief 타입에는 없음 */
|
||||
type Brief = ElementBrief & { 구분?: string; 상세구분?: string };
|
||||
|
||||
const TEXT = {
|
||||
Title: ["넣을 것 고르기", "Pick what to add"],
|
||||
@@ -136,13 +138,13 @@ const SOURCES: Partial<Record<Kind, Source>> = {
|
||||
? await fetchPick("price", f.q).then((r) => ({
|
||||
total: r.total,
|
||||
items: r.items
|
||||
.filter((it) => !f.sub || (it as { 구분?: string }).구분 === f.sub)
|
||||
.map((it) => ({ ...it, 구분: (it as { 구분?: string }).구분, 상세구분: undefined })),
|
||||
.filter((it) => !f.sub || (it as Brief).구분 === f.sub)
|
||||
.map((it) => ({ ...it, 구분: (it as Brief).구분 })),
|
||||
}))
|
||||
: await fetchMaterials({ sub: f.sub, ...(f.detail ? { detail: f.detail } : {}) }).then(
|
||||
(r) => ({
|
||||
total: r.total,
|
||||
items: r.items.map((it) => ({ ...it, 구분: it.구분 ?? f.sub })),
|
||||
items: r.items.map((it) => ({ ...it, 구분: (it as Brief).구분 ?? f.sub })),
|
||||
}),
|
||||
);
|
||||
return {
|
||||
@@ -153,7 +155,7 @@ const SOURCES: Partial<Record<Kind, Source>> = {
|
||||
const unit = typeof it.단위 === "string" ? it.단위 : "";
|
||||
const price = num(it.값);
|
||||
const element: Record<string, string> = { 구분: it.구분 ?? f.sub };
|
||||
const detail = (it as { 상세구분?: string }).상세구분;
|
||||
const detail = (it as Brief).상세구분;
|
||||
if (detail) element["상세구분"] = detail;
|
||||
element["검색어"] = `${name} ${spec}`.trim();
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user