Files

143 lines
5.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const EstViews = (() => {
const enums = {
LinkIndex: [
[0, "직접입력"],
[5, "자재"],
[6, "노임"],
[21, "표준"],
[101, "견적"],
[103, "일위"],
[104, "단가산출"],
[105, "기계"],
[51, "소계"],
[52, "낙찰"],
[54, "순공사비"],
[55, "도급액"],
[57, "조달수수료"],
[58, "비율"],
[59, "경계"],
[61, "산근 소계"],
[62, "구간비율"],
[67, "내역비율"],
[68, "묶음끝"],
[99, "연차 배분"],
],
CalcIndex: [
[0, "계산·합산"],
[1, "고정·합산"],
[2, "계산·제외"],
[3, "고정·제외"],
],
ValueIndex: [
[0, "최저"],
[1, "평균"],
[2, "최고"],
[3, "출처선택"],
[4, "직접입력"],
],
DigetIndex: [
[0, "AUTO"],
[1, "사사오입"],
[2, "절사"],
[3, "올림식"],
],
SCheck: [
[0, "비목별"],
[1, "재료"],
[2, "노무"],
[3, "경비"],
[-1, "노무 소계"],
[-2, "재료 소계"],
[-3, "경비 소계"],
[-4, "실적 소계"],
[-5, "합계"],
],
BaseField: [
["", "직접 입력"],
["NC", "직접 노무"],
["GC", "직접 재료"],
["JC", "직접 경비"],
["SC", "직접 실적"],
["TC", "순공사비"],
],
};
function cell(table, index, key, value) {
const { esc } = EstApp,
label = EstModel.labels[key] || key;
const attrs = `data-table="${table}" data-row="${index}" data-field="${key}" aria-label="${esc(label)}"`;
if (enums[key])
return `<select ${attrs}>${enums[key].map(([v, name]) => `<option value="${v}" ${String(v) === String(value ?? (key === "BaseField" ? "" : 0)) ? "selected" : ""}>${esc(name)}</option>`).join("")}</select>`;
if (key === "LineData")
return `<textarea ${attrs} rows="1" spellcheck="false">${esc(EstText.display(value))}</textarea><button class="tiny" data-action="raw-line" data-row="${index}" title="산출근거 편집">…</button>`;
if (value && typeof value === "object") return `<span class="muted">바이너리 자료</span>`;
if (EstModel.numeric.has(key))
return `<input ${attrs} inputmode="decimal" type="number" step="any" value="${value ?? ""}">`;
return `<input ${attrs} type="text" value="${esc(value)}" maxlength="10000">`;
}
function grid(table, list, columns) {
const { esc, number, state } = EstApp;
return `<table class="sheet" data-grid="${table}"><thead><tr><th class="row-number">선택</th>${columns.map((key) => `<th class="col-${key}">${esc(EstModel.labels[key] || key)}</th>`).join("")}</tr></thead><tbody>${list.map(({ row, index }) => `<tr data-index="${index}" class="${state.selection.has(index) ? "selected " : ""}${Number(row.Index) > 0 ? "heading " : ""}${Number(row.Level) > 0 ? "level " : ""}${row.Error ? "error-row" : ""}"><th class="row-number"><label><input type="checkbox" data-select="${index}" ${state.selection.has(index) ? "checked" : ""}>${index + 1}</label></th>${columns.map((key) => `<td class="col-${key}">${cell(table, index, key, row[key])}</td>`).join("")}</tr>`).join("")}</tbody></table>`;
}
function render(state) {
const { project, view } = state,
{ byId, esc, number } = EstApp;
if (project.tables[view]) EstApp.visibleRows();
const grouped = ["HeadMainDat", "CostMainDat", "MachMainDat"].includes(view);
byId("group-pane").hidden = !grouped;
if (grouped) {
const records = EstNative.groups(project.tables[view] || []);
byId("group-list").innerHTML =
[...records]
.map(
([code, group]) =>
`<button data-group="${esc(code)}" class="${state.group === code ? "active" : ""}"><b>${esc(group.rows[0].Name || EstText.clean(group.rows[0].LineData))}</b><small>${esc(code)}</small><span>${number(group.rows[0].TC)}</span></button>`,
)
.join("") || '<p class="muted">자료가 없습니다. 묶음 추가를 누르세요.</p>';
}
byId("search").value = state.query;
byId("business-search").value = state.query;
byId("business-search").hidden = !["progress", "escalation", "change"].includes(view);
byId("standard-tools").hidden = !project.tables[view];
byId("add-group").hidden = !grouped;
const haljungBtn = byId("haljung-calc-btn");
if (haljungBtn) haljungBtn.hidden = view !== "HeadMainDat";
const vatBtn = byId("vat-calc-btn");
if (vatBtn) vatBtn.hidden = view !== "StuffcDat";
const unitCalcBtn = byId("unit-calc-btn");
if (unitCalcBtn) unitCalcBtn.hidden = view !== "HeadMainDat";
byId("move-estimate-up").hidden = ![
"EstMainDat",
"HeadMainDat",
"CostMainDat",
"MachMainDat",
].includes(view);
byId("move-estimate-down").hidden = ![
"EstMainDat",
"HeadMainDat",
"CostMainDat",
"MachMainDat",
].includes(view);
if (project.tables[view]) {
const all = EstApp.visibleRows(),
start = state.page * 100,
list = all.slice(start, start + 100),
columns = EstModel.columns(view);
byId("work-content").innerHTML = grid(view, list, columns);
byId("paging").hidden = false;
byId("page-info").textContent =
`${all.length ? start + 1 : 0}–${Math.min(start + 100, all.length)} / ${all.length}행`;
byId("previous-page").disabled = state.page === 0;
byId("next-page").disabled = start + 100 >= all.length;
} else {
byId("paging").hidden = true;
EstExtra.render(state);
}
const chosen = [...state.selection][0],
row = project.tables[view]?.[chosen];
byId("selected-info").textContent = row
? `${chosen + 1}행 · ${row.Code || ""} ${row.Name || EstText.clean(row.LineData)}`
: "행 왼쪽을 선택한 뒤 복사·삭제·레벨 지정 등을 사용할 수 있습니다.";
}
return { render, grid, cell, enums };
})();