import { defaultSheet, FIELD_LABELS, parseSheetConfig, REFERENCE_TEMPLATE } from './template'; import type { SheetConfig } from './types'; export function createSheetEditor(host:HTMLElement,apply:(config:SheetConfig)=>void):{open:(value:SheetConfig)=>void}{ const dialog=window.document.createElement('dialog');dialog.className='ga-sheet-dialog';dialog.setAttribute('aria-label','도곽 및 노트 편집'); dialog.innerHTML=`
원본 도곽 · NOTE 편집

첨부 DWG의 CXBLKA1 도곽·표제란과 NOTE 원문입니다. 강도·시공 조건은 현 프로젝트에 맞게 검토하여 수정하세요. {{project}}, {{bridge}}, {{pier}}, {{scale}}, {{paper}}는 현재 도면 값으로 치환됩니다.

표제란 속성 · 원본 위치/글자 크기 유지

NOTE 원문

REFERENCE

`; host.append(dialog); const node=(id:string)=>dialog.querySelector(`#${id}`)!; let working=defaultSheet(); const populate=(config:SheetConfig)=>{ working=structuredClone(config);const template=working.template??REFERENCE_TEMPLATE; node('ga-template-name').textContent=`${template.name} · ${template.source}`; node('ga-frame-show').checked=working.showFrame;node('ga-logo-show').checked=working.showLogo; node('ga-note-height').value=String(working.noteHeight);node('ga-note-text').value=working.notes;node('ga-reference-text').value=working.references; node('ga-start-label').value=working.startLabel;node('ga-end-label').value=working.endLabel; const fields=node('ga-frame-fields');fields.replaceChildren(); for(const field of template.fields){const row=window.document.createElement('label'),label=window.document.createElement('span'),input=window.document.createElement('input'); label.textContent=FIELD_LABELS[field.tag]??field.label??field.tag;input.value=working.fields[field.tag]??field.value;input.dataset.tag=field.tag;input.maxLength=500;input.setAttribute('aria-label',`${label.textContent} (${field.tag})`); const small=window.document.createElement('small');small.textContent=field.tag;row.append(label,input,small);fields.append(row); } }; const collect=():SheetConfig=>{ const fields={...working.fields};for(const input of node('ga-frame-fields').querySelectorAll('[data-tag]'))fields[input.dataset.tag!]=input.value; return parseSheetConfig({...working,fields,showFrame:node('ga-frame-show').checked,showLogo:node('ga-logo-show').checked,noteHeight:Number(node('ga-note-height').value),notes:node('ga-note-text').value,references:node('ga-reference-text').value,startLabel:node('ga-start-label').value,endLabel:node('ga-end-label').value}); }; const status=(s:string)=>node('ga-editor-status').textContent=s; node('ga-editor-close').addEventListener('click',()=>dialog.close());node('ga-config-reset').addEventListener('click',()=>populate(defaultSheet())); node('ga-config-apply').addEventListener('click',()=>{try{apply(collect());dialog.close();}catch(error){status((error as Error).message);}}); node('ga-config-import').addEventListener('click',()=>node('ga-config-file').click()); node('ga-config-file').addEventListener('change',async event=>{ const file=(event.target as HTMLInputElement).files?.[0];if(!file)return; try{if(file.size>1500000)throw new Error('설정 파일은 1.5MB 이하만 지원합니다.');populate(parseSheetConfig(JSON.parse(await file.text())));status('불러왔습니다. 적용 버튼으로 현재 도면에 반영하세요.');}catch(error){status((error as Error).message);}(event.target as HTMLInputElement).value=''; }); node('ga-config-export').addEventListener('click',()=>{try{const c=collect(),url=URL.createObjectURL(new Blob([JSON.stringify({...c,template:c.template??REFERENCE_TEMPLATE},null,2)],{type:'application/json'})),link=window.document.createElement('a');link.href=url;link.download='Pierzainer_도곽_노트.json';link.click();setTimeout(()=>URL.revokeObjectURL(url),1000);}catch(error){status((error as Error).message);}}); return{open:value=>{populate(value);dialog.showModal();}}; }