feat(import): 엑셀 불러오기 미리보기에 전체 교각의 입력값 표시
- 교각 정보: 교각마다 열 하나, 행은 형식·EL·기초·말뚝·두부보·기둥·받침/IP 수·불러오기 여부 - 받침과 IP: 모든 교각을 한 표에 두고 교각 열을 추가, 표는 스크롤 - 교각 이름 클릭으로 미리볼 교각을 고르던 방식은 제거 (전체를 보여 줌) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
844177b40e
commit
b0a71fc73f
3 files changed
+55
-43
No files matched your search
+39
-34
@@ -108,7 +108,6 @@ interface Pending {
|
||||
fileName: string;
|
||||
entries: Pier[];
|
||||
sheets: SheetReport[];
|
||||
preview: string | null;
|
||||
}
|
||||
|
||||
const state = {
|
||||
@@ -2842,7 +2841,7 @@ function renderDialog(): void {
|
||||
$('file-name').textContent = p ? `선택된 파일: ${p.fileName}` : '';
|
||||
if (!p) {
|
||||
sheetsBox.appendChild(el('li', '파일을 선택하면 시트별 인식 결과가 표시됩니다.'));
|
||||
renderPreview(null);
|
||||
renderPreview([]);
|
||||
updateApply();
|
||||
return;
|
||||
}
|
||||
@@ -2873,38 +2872,36 @@ function renderDialog(): void {
|
||||
entry.checked = check.checked;
|
||||
updateApply();
|
||||
});
|
||||
const name = el('button', `${entry.input.name} · ${entry.input.type}`, 'pier-name');
|
||||
name.type = 'button';
|
||||
name.setAttribute('aria-pressed', String(p.preview === entry.input.name));
|
||||
name.addEventListener('click', () => {
|
||||
p.preview = entry.input.name;
|
||||
renderDialog();
|
||||
});
|
||||
const name = el('span', `${entry.input.name} · ${entry.input.type}`, 'pier-name');
|
||||
row.append(check, name);
|
||||
li.appendChild(row);
|
||||
}
|
||||
sheetsBox.appendChild(li);
|
||||
}
|
||||
const preview = p.entries.find((e) => e.input.name === p.preview) ?? p.entries.find((e) => selectable(p, e)) ?? null;
|
||||
renderPreview(preview ? preview.input : null);
|
||||
renderPreview(p ? p.entries.map((e) => ({ input: e.input, checked: e.checked })) : []);
|
||||
updateApply();
|
||||
}
|
||||
|
||||
function renderPreview(input: PierInput | null): void {
|
||||
/** Preview of every pier in the file: one column per pier for the 교각 정보, all 받침·IP rows with a 교각 column. */
|
||||
function renderPreview(items: { input: PierInput; checked: boolean }[]): void {
|
||||
const title = $('preview-title');
|
||||
const pierTable = $<HTMLTableElement>('pv-pier').tBodies[0];
|
||||
const pierTable = $<HTMLTableElement>('pv-pier');
|
||||
const bearingBody = $<HTMLTableElement>('pv-bearings').tBodies[0];
|
||||
const ipBody = $<HTMLTableElement>('pv-ips').tBodies[0];
|
||||
pierTable.replaceChildren();
|
||||
bearingBody.replaceChildren();
|
||||
ipBody.replaceChildren();
|
||||
if (!input) {
|
||||
if (items.length === 0) {
|
||||
title.textContent = '미리볼 교각이 없습니다.';
|
||||
return;
|
||||
}
|
||||
title.textContent = `${input.name} · 시트 ${input.sheet}`;
|
||||
const pairs: Pair[] = [
|
||||
['교각명', input.name],
|
||||
const sheets = [...new Set(items.map((i) => i.input.sheet))].join(', ');
|
||||
title.textContent = `${items.length}기 · 시트 ${sheets}`;
|
||||
|
||||
const head = pierTable.createTHead().insertRow();
|
||||
head.appendChild(el('th', '항목'));
|
||||
for (const { input } of items) head.appendChild(el('th', input.name));
|
||||
const rowsOf = (input: PierInput): Pair[] => [
|
||||
['교각형식', input.type],
|
||||
['두부보 EL (코핑 상면)', f3(input.copingTopEl)],
|
||||
['기초 하단 EL', f3(input.footingBottomEl)],
|
||||
@@ -2913,22 +2910,31 @@ function renderPreview(input: PierInput | null): void {
|
||||
['말뚝길이 (mm)', String(input.pileLengthMm)],
|
||||
['두부보 폭 × 길이 (mm)', `${input.copingWidthMm} × ${input.copingLengthMm}`],
|
||||
['기둥갯수', String(input.columnCount)],
|
||||
['받침 · IP', `${input.bearings.length} · ${input.ips.length}`],
|
||||
];
|
||||
for (const [k, v] of pairs) {
|
||||
const tr = el('tr');
|
||||
tr.append(el('th', k), el('td', v));
|
||||
pierTable.appendChild(tr);
|
||||
}
|
||||
for (const b of input.bearings) {
|
||||
const tr = el('tr');
|
||||
const azimuth = Number.isNaN(b.azimuthDeg) ? '오류' : `${b.azimuthDeg.toFixed(4)}°`;
|
||||
for (const v of [String(b.no), b.x.toFixed(3), b.y.toFixed(3), f3(b.z), azimuth, b.row]) tr.appendChild(el('td', v));
|
||||
bearingBody.appendChild(tr);
|
||||
}
|
||||
for (const ip of input.ips) {
|
||||
const tr = el('tr');
|
||||
for (const v of [ip.name, ip.x.toFixed(3), ip.y.toFixed(3), `${ip.angleDeg}°`]) tr.appendChild(el('td', v));
|
||||
ipBody.appendChild(tr);
|
||||
const labels = rowsOf(items[0].input).map(([k]) => k);
|
||||
const body = pierTable.createTBody();
|
||||
labels.forEach((label, r) => {
|
||||
const tr = body.insertRow();
|
||||
tr.appendChild(el('th', label));
|
||||
for (const { input } of items) tr.appendChild(el('td', rowsOf(input)[r][1]));
|
||||
});
|
||||
const included = body.insertRow();
|
||||
included.appendChild(el('th', '불러오기'));
|
||||
for (const { checked } of items) included.appendChild(el('td', checked ? '예' : '아니오'));
|
||||
|
||||
for (const { input } of items) {
|
||||
for (const b of input.bearings) {
|
||||
const tr = el('tr');
|
||||
const azimuth = Number.isNaN(b.azimuthDeg) ? '오류' : `${b.azimuthDeg.toFixed(4)}°`;
|
||||
for (const v of [input.name, String(b.no), b.x.toFixed(3), b.y.toFixed(3), f3(b.z), azimuth, b.row]) tr.appendChild(el('td', v));
|
||||
bearingBody.appendChild(tr);
|
||||
}
|
||||
for (const ip of input.ips) {
|
||||
const tr = el('tr');
|
||||
for (const v of [input.name, ip.name, ip.x.toFixed(3), ip.y.toFixed(3), `${ip.angleDeg}°`]) tr.appendChild(el('td', v));
|
||||
ipBody.appendChild(tr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2952,9 +2958,8 @@ function loadBytes(bytes: Uint8Array, fileName: string): void {
|
||||
for (const e of own) sheet.issues.push(...e.issues.filter((i) => i.level === 'E'));
|
||||
sheet.ok = sheet.ok && own.every((e) => e.model !== null);
|
||||
}
|
||||
const pending: Pending = { fileName, entries, sheets, preview: null };
|
||||
const pending: Pending = { fileName, entries, sheets };
|
||||
for (const e of entries) e.checked = selectable(pending, e);
|
||||
pending.preview = entries.find((e) => selectable(pending, e))?.input.name ?? entries[0]?.input.name ?? null;
|
||||
state.pending = pending;
|
||||
renderDialog();
|
||||
}
|
||||
|
||||
@@ -810,3 +810,6 @@ body { background: #eef1f4; font-family: 'Noto Sans KR', system-ui, sans-serif;
|
||||
@media (max-width: 800px) {
|
||||
.footing-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
/* Import preview: all piers' 받침·IP rows scroll inside the dialog. */
|
||||
.pv-scroll { max-height: 240px; overflow: auto; }
|
||||
Reference in new issue
Block a user