143 lines
5.9 KiB
JavaScript
143 lines
5.9 KiB
JavaScript
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 };
|
||
})();
|