fix(M01): 잡힌 품목 이름 · 모달 검색 칸 괄호 앞 낱말 · 상세 재료 줄 모달 서버 품목 · 단위경고 딱지 상세 줄에도 (PLAN 8-5)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WRFJmmhPi4exAzHgPZHMT
This commit is contained in:
@@ -10,7 +10,6 @@
|
||||
|
||||
import { createButton, el } from "@ui/ui_template_elements";
|
||||
import {
|
||||
fetchMaterials,
|
||||
searchElements,
|
||||
type ElementBrief,
|
||||
type NamedFormula,
|
||||
@@ -46,7 +45,18 @@ export interface PickCond {
|
||||
export const condText = (cond: PickCond): string =>
|
||||
["구분", "상세구분", "이름", "규격", "대표", "지역", "계약종별"]
|
||||
.map((k) => String(cond[k] ?? ""))
|
||||
.join("|");
|
||||
.join("|") + (cond["검색어"] ? `|${cond["검색어"]}` : "");
|
||||
|
||||
/** 재료 모달 검색 칸 글 — 검색어 첫 낱말의 괄호 앞(「합판(내수) 12t」 → 「합판」) */
|
||||
export const headWord = (text: unknown): string =>
|
||||
String(text ?? "")
|
||||
.trim()
|
||||
.split(/\s+/)[0]
|
||||
.replace(/[((].*$/, "");
|
||||
|
||||
/** 고르기 줄 후보 찾기 글 — 검색어 → 이름 → 상세구분 → 구분 차례 첫 낱말 */
|
||||
export const seedOf = (cond: PickCond): string =>
|
||||
[cond["검색어"], cond.이름, cond.상세구분, cond.구분].map(headWord).find(Boolean) ?? "";
|
||||
|
||||
export interface ModalTarget {
|
||||
title: string;
|
||||
@@ -227,19 +237,12 @@ const muted = (text: string): HTMLElement => el("p", { className: "m01-logic__mu
|
||||
/** 재료 고르기 줄 후보 목록 — 잡힌 품목(`pickedRef`)을 노란 줄로 · 후보가 100건을 넘으면 앞 100건만 옴 */
|
||||
function candidateView(
|
||||
cond: PickCond,
|
||||
unit: string,
|
||||
pickedRef: string,
|
||||
onPicked: (item: ElementBrief | null) => void,
|
||||
): HTMLElement {
|
||||
const box = el("div", { className: "m01lab__data", attrs: { "data-candidates": "1" } });
|
||||
box.append(muted("…"));
|
||||
void fetchMaterials({
|
||||
sub: String(cond["구분"] ?? ""),
|
||||
detail: String(cond["상세구분"] ?? ""),
|
||||
spec: String(cond["규격"] ?? ""),
|
||||
region: "",
|
||||
unit,
|
||||
})
|
||||
void searchElements("재료", seedOf(cond))
|
||||
.then((got) => {
|
||||
onPicked(got.items.find((it) => it.ref === pickedRef) ?? null);
|
||||
const rows = got.items.map((it) =>
|
||||
@@ -301,12 +304,17 @@ export function openMaterialModal(target: ModalTarget): void {
|
||||
const element = target.element ?? "";
|
||||
const base = element.split(".")[0];
|
||||
// 고르기 줄 = 서버가 조건 글을 열쇠로 준 줄(대표가 안 정해졌으면 없음)
|
||||
const priced = cond ? target.prices[condText(cond)] : undefined;
|
||||
const known = cond
|
||||
? target.prices[condText(cond)]
|
||||
? target.unitRef && priced?.ref !== target.unitRef
|
||||
? undefined // 서버가 잡은 품목이 다르면 그 품목으로
|
||||
: priced
|
||||
: element
|
||||
? (target.prices[element] ?? target.prices[base])
|
||||
: undefined;
|
||||
const priceRef = cond ? pickedOf(cond, target.values, known?.ref ?? "") : element;
|
||||
const priceRef = cond
|
||||
? target.unitRef || pickedOf(cond, target.values, known?.ref ?? "")
|
||||
: element;
|
||||
const logicKey = /^로직\((\w+)/.exec(element)?.[1] ?? "";
|
||||
const sum = el("p", { className: "m01lab__sum" });
|
||||
const setSum = (price: ElementBrief | null | undefined): void => {
|
||||
@@ -366,7 +374,7 @@ export function openMaterialModal(target: ModalTarget): void {
|
||||
rate,
|
||||
...(cond
|
||||
? [
|
||||
candidateView(cond, target.unit ?? "", priceRef, (item) => {
|
||||
candidateView(cond, priceRef, (item) => {
|
||||
if (known || !priceRef) return;
|
||||
const show = (brief: ElementBrief | null): void => {
|
||||
rate.replaceChildren(
|
||||
|
||||
Reference in New Issue
Block a user