Files
Pier_v1/수량산출/review-panel.ts
T

30 lines
4.2 KiB
TypeScript
Raw 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.
import type {PierModel} from '../src/core/geometry';
import {createExcelPreview} from './excel-preview';
import {DETAIL,INPUTS,extraNumbers} from './schema';
import {cellKey} from './formula';
import {node,fmt,type TakeoffResult,type Selection} from './dashboard-types';
import {rowStatus} from './results-panel';
import type {QuantityInputs} from './model';
export function createReviewPanel(o:{result:TakeoffResult;stored:QuantityInputs;pier:string;project:{name:string;bridge:string};plan:{selected:PierModel;models:readonly PierModel[]};stale:boolean;miniState:{sheet:string;zoom:number};onCell:(cell:string)=>void}){
const panel=node('aside',undefined,'tq-right-panel'),preview=node('section',undefined,'tq-panel tq-mini-panel');const heading=node('div',undefined,'tq-panel-heading');heading.append(node('h3','산출서 미리보기'));const expand=node('button','⛶');expand.type='button';expand.setAttribute('aria-label','산출서 미리보기 전체화면');heading.append(expand);preview.append(heading);
const mini=createExcelPreview({result:o.result,stored:o.stored,pier:o.pier,project:o.project,plan:o.plan,state:o.miniState,compact:true,onCell:o.onCell});preview.append(mini);panel.append(preview);
const trace=node('section',undefined,'tq-panel tq-formula-panel takeoff-trace');trace.setAttribute('aria-live','polite');panel.append(trace);
expand.onclick=()=>{const dialog=node('dialog',undefined,'tq-preview-dialog');dialog.dataset.quantityPreviewDialog='true';dialog.setAttribute('aria-label','수량산출서 전체화면');const close=node('button','닫기 ×');close.type='button';close.className='tq-dialog-close';close.onclick=()=>dialog.close();dialog.append(close,createExcelPreview({result:o.result,stored:o.stored,pier:o.pier,project:o.project,plan:o.plan,state:{sheet:'__all__',zoom:1},onCell:o.onCell}));dialog.addEventListener('close',()=>{dialog.remove();expand.focus({preventScroll:true});},{once:true});document.body.append(dialog);dialog.showModal();};
const select=(s:Selection)=>{
trace.replaceChildren(node('h3','산식 상세'),node('p',s.title,'tq-selected-title'));
const block=(label:string,content:HTMLElement)=>{const row=node('div',undefined,'tq-formula-block');row.append(node('b',label),content);trace.append(row);};
block('산식',node('pre',s.rows.length===1?String(s.rows[0].description??s.formula):s.formula));
const inputs=node('dl',undefined,'tq-formula-inputs');const deps=new Set(s.rows.flatMap(r=>r.dependencies));
for(const v of o.result.mapped){const key=cellKey(INPUTS,'N'+v.key.slice(1));if(!deps.has(key))continue;let value:string;try{value=String(o.result.book.cell(INPUTS,'N'+v.key.slice(1)));}catch{value='미입력';}inputs.append(node('dt',v.symbol+' · '+v.name),node('dd',value+' '+v.unit));}
for(const v of extraNumbers){if(!deps.has(cellKey(DETAIL,v.cell)))continue;let value:string;try{value=String(o.result.book.cell(DETAIL,v.cell));}catch{value='미입력';}inputs.append(node('dt',v.name),node('dd',value+' '+v.unit));}
if(inputs.children.length)block('입력값',inputs);
block('계산식',node('pre',s.substitution));
const answer=node('div',undefined,'tq-formula-answer');answer.append(node('b','결과'),node('strong',fmt(s.value)+' '+s.unit));const status=rowStatus(s.rows,o.stale,!!o.result.issues.length,o.stored.reviewed);answer.append(node('span',status.text,'tq-status-tag '+status.kind));trace.append(answer);
const source=node('details',undefined,'tq-formula-source');source.append(node('summary','원본식 · 중간 계산값 · 참조 셀'));source.append(node('pre',s.formula));
for(const r of s.rows)if(r.formula!==r.sourceFormula)source.append(node('p',r.cell+' · 직선 모델: 원본 곡률항의 R→∞ 극한 적용'),node('pre','원본: '+r.sourceFormula));
for(const key of deps){const ix=key.lastIndexOf('!'),sheet=key.slice(0,ix),cell=key.slice(ix+1);if(s.rows.some(r=>sheet===DETAIL&&r.cell===cell))continue;let value:string;try{value=String(o.result.book.cell(sheet,cell));}catch{value='미입력';}source.append(node('p',key+' = '+value));}trace.append(source);
mini.dispatchEvent(new CustomEvent('takeoff:focus-cells',{detail:s.rows.map(r=>r.cell)}));
};
return {panel,select,focusPreview:()=>{preview.tabIndex=-1;preview.focus();}};
}