feat(M02): 일위대가 수량산출 열 — 위 결과단위 기준 수량 · 아래 지금 수량 · 누르면 손 입력 / 엑셀에서 고르기(면적 칸 연결 · [저장] 때 면적 문서 함께) · 버튼 공용 양식(40-1 ④ ⑤)
- Labor_Rows 수량산출 칸(qtyCell) · 결과 단위 왼쪽 · 좁은 칸은 윗줄 - Labor_Input 수량 칸에 [엑셀에서 고르기](sub3 pickAreaCell) · 이으면 손 수량 지움 · 모달 닫음 - Labor_Detail: 면적 문서 · 판을 들고 linkAreaCell · recalcWorkbook · 저장 안 한 연결은 calc 에 칸 값으로 · saveArea - UI_Main labor 갈래: [저장] = 면적 문서 먼저 → 일위대가 판 다시 읽음 → 일위대가(서버가 면적 저장 때 일위대가 계산값을 다시 적어 판이 바뀜) - 로직 추가 · 자재 추가 · 올리기 · 내리기 · 빼기 = 기본 크기 버튼(sm 알약 꼴 아님) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
This commit is contained in:
@@ -33,6 +33,8 @@ export interface QtySeat {
|
||||
linked: string | null;
|
||||
/** 손 입력 단위 표기(분모 · 자재 단위) */
|
||||
unit: string;
|
||||
/** [엑셀에서 고르기](40-1) — 그 열 면적산출 칸을 골라 이음 · 이었으면 참(모달 닫음) · 없으면 단추 없음 */
|
||||
pick?: (() => Promise<boolean>) | null;
|
||||
}
|
||||
|
||||
interface QtyPart {
|
||||
@@ -42,7 +44,12 @@ interface QtyPart {
|
||||
}
|
||||
|
||||
/** 수량 칸 — 「면적산출 칸」 / 「손 입력」 · 손이 칸보다 앞섬 */
|
||||
function qtyPart(seat: QtySeat, readOnly: boolean, goArea: (() => void) | null): QtyPart {
|
||||
function qtyPart(
|
||||
seat: QtySeat,
|
||||
readOnly: boolean,
|
||||
goArea: (() => void) | null,
|
||||
close: () => void,
|
||||
): QtyPart {
|
||||
const name = `m02-labin-qty-${Math.random().toString(36).slice(2)}`;
|
||||
const radio = (value: "cell" | "hand"): HTMLInputElement => {
|
||||
const input = el("input", { attrs: { type: "radio", name, value } }) as HTMLInputElement;
|
||||
@@ -67,6 +74,16 @@ function qtyPart(seat: QtySeat, readOnly: boolean, goArea: (() => void) | null):
|
||||
const go = goArea
|
||||
? createButton({ label: tc("In_QtyGoArea"), variant: "ghost", size: "sm", onClick: goArea })
|
||||
: null;
|
||||
const pickFn = seat.pick;
|
||||
const pick =
|
||||
pickFn && !readOnly
|
||||
? createButton({
|
||||
label: tc("In_QtyPick"),
|
||||
variant: "ghost",
|
||||
size: "sm",
|
||||
onClick: () => void pickFn().then((linked) => linked && close()),
|
||||
})
|
||||
: null;
|
||||
const line = (input: HTMLInputElement, label: string, ...rest: HTMLElement[]): HTMLElement =>
|
||||
el("label", {
|
||||
className: "m02-labin__qty-line",
|
||||
@@ -83,6 +100,7 @@ function qtyPart(seat: QtySeat, readOnly: boolean, goArea: (() => void) | null):
|
||||
className: "m02-labin__muted",
|
||||
text: seat.linked ? fill(tc("In_QtyLinked"), seat.linked) : tc("In_QtyNoLink"),
|
||||
}),
|
||||
...(pick ? [pick] : []),
|
||||
...(go ? [go] : []),
|
||||
),
|
||||
line(hand, tc("In_QtyHand"), number, el("small", { text: seat.unit })),
|
||||
@@ -174,7 +192,7 @@ export function openLaborInput(opt: LaborInputOptions): void {
|
||||
}) as HTMLInputElement;
|
||||
memo.value = opt.memo ?? "";
|
||||
memo.readOnly = opt.readOnly;
|
||||
const qty = qtyPart(opt.seat, opt.readOnly, opt.goArea && leaveTo(opt.goArea, close));
|
||||
const qty = qtyPart(opt.seat, opt.readOnly, opt.goArea && leaveTo(opt.goArea, close), close);
|
||||
const ok = (): void => {
|
||||
if (bad.size) return showToast(tc("In_Bad"), "error");
|
||||
const 수량 = qty.read();
|
||||
@@ -226,7 +244,7 @@ export function openQtyModal(
|
||||
closeLabel: tc("In_Close"),
|
||||
dialogClass: "m02-modal m02-labin",
|
||||
mount: (body, close) => {
|
||||
const qty = qtyPart(seat, readOnly, goArea && leaveTo(goArea, close));
|
||||
const qty = qtyPart(seat, readOnly, goArea && leaveTo(goArea, close), close);
|
||||
const ok = (): void => {
|
||||
const 수량 = qty.read();
|
||||
if (수량 === undefined) return showToast(tc("In_QtyNeed"), "error");
|
||||
|
||||
Reference in New Issue
Block a user