Document package formats, release workflows, deployment planning and UI concepts. Closes #1
165 lines
30 KiB
HTML
165 lines
30 KiB
HTML
<style>
|
||
#eg-wizard-design { width:100%; }
|
||
#eg-wizard-design .ew-stage { min-height:690px; }
|
||
#eg-wizard-design .ew-preview,#eg-wizard-design .ew-app { --ew-bg:light-dark(#ffffff,#20252d); --ew-soft:light-dark(#f4f6f9,#191e26); --ew-line:light-dark(#dce2ea,#3c4553); --ew-ink:light-dark(#202c3d,#edf2fa); --ew-muted:light-dark(#5f6d80,#b0bdce); --ew-blue:light-dark(#2656bd,#a6c0ff); --ew-on:light-dark(#ffffff,#112956); --ew-wash:light-dark(#edf3ff,#293a57); --ew-good:light-dark(#246b50,#94d9b7); --ew-warn:light-dark(#865517,#efc280); --ew-bad:light-dark(#a63532,#ffb0ac); color:var(--ew-ink); font:14px/1.6 'Segoe UI','Malgun Gothic',sans-serif; }
|
||
#eg-wizard-design * { box-sizing:border-box; }
|
||
#eg-wizard-design .ew-preview { display:flex; flex-wrap:wrap; align-items:flex-end; gap:8px; padding:14px 0; padding-right:92px; }
|
||
#eg-wizard-design .ew-preview label { display:grid; gap:4px; font-size:11px; color:var(--ew-muted); }
|
||
#eg-wizard-design .ew-preview select { max-width:100%; background:var(--ew-bg); color:var(--ew-ink); border:1px solid var(--ew-line); border-radius:5px; padding:6px 8px; font:12px/1.5 'Segoe UI','Malgun Gothic',sans-serif; }
|
||
#eg-wizard-design button { font:500 12px/1.5 'Segoe UI','Malgun Gothic',sans-serif; }
|
||
#eg-wizard-design .ew-button { display:inline-flex; justify-content:center; align-items:center; gap:7px; min-height:34px; padding:7px 16px; border:1px solid var(--ew-line); border-radius:5px; color:var(--ew-ink); background:var(--ew-bg); }
|
||
#eg-wizard-design button:disabled { opacity:.48; cursor:not-allowed; }
|
||
#eg-wizard-design .ew-primary { background:var(--ew-blue); color:var(--ew-on); border-color:var(--ew-blue); }
|
||
#eg-wizard-design .ew-link { background:transparent; border:0; color:var(--ew-blue); padding:5px 0; }
|
||
#eg-wizard-design .ew-app { background:var(--ew-bg); border:1px solid var(--ew-line); border-radius:9px; overflow-wrap:anywhere; box-shadow:0 8px 30px light-dark(#17305710,#00000025); }
|
||
#eg-wizard-design .ew-title { min-height:44px; display:flex; gap:9px; align-items:center; padding:10px 18px; border-bottom:1px solid var(--ew-line); font-size:12px; }
|
||
#eg-wizard-design .ew-mark { display:grid; place-items:center; width:23px; height:23px; background:var(--ew-blue); color:var(--ew-on); border-radius:5px; font-weight:600; flex-shrink:0; }
|
||
#eg-wizard-design .ew-tag { margin-left:auto; font-size:11px; color:var(--ew-muted); }
|
||
#eg-wizard-design .ew-layout { display:grid; grid-template-columns:154px minmax(0,1fr); min-height:480px; }
|
||
#eg-wizard-design .ew-side { background:var(--ew-soft); padding:28px 18px; border-right:1px solid var(--ew-line); }
|
||
#eg-wizard-design .ew-side-brand { font-size:17px; font-weight:600; letter-spacing:-.6px; margin-bottom:4px; }
|
||
#eg-wizard-design .ew-side-sub { color:var(--ew-muted); font-size:11px; }
|
||
#eg-wizard-design .ew-steps { list-style:none; display:grid; gap:21px; margin:34px 0 0; padding:0; }
|
||
#eg-wizard-design .ew-steps li { display:flex; align-items:center; gap:9px; color:var(--ew-muted); font-size:12px; }
|
||
#eg-wizard-design .ew-number { display:grid; place-items:center; width:22px; height:22px; border:1px solid var(--ew-line); border-radius:50%; font-size:11px; flex-shrink:0; }
|
||
#eg-wizard-design .ew-steps [aria-current=step] { color:var(--ew-blue); font-weight:600; }
|
||
#eg-wizard-design .ew-steps [aria-current=step] .ew-number { background:var(--ew-blue); color:var(--ew-on); border-color:transparent; }
|
||
#eg-wizard-design .ew-past .ew-number { color:var(--ew-good); }
|
||
#eg-wizard-design .ew-main { min-width:0; }
|
||
#eg-wizard-design .ew-page-heading { padding:23px 26px 18px; border-bottom:1px solid var(--ew-line); }
|
||
#eg-wizard-design .ew-page-heading h2 { margin:0 0 5px; font-size:19px; font-weight:600; letter-spacing:-.6px; }
|
||
#eg-wizard-design .ew-page-heading p { margin:0; color:var(--ew-muted); font-size:12px; }
|
||
#eg-wizard-design .ew-body { padding:22px 26px; }
|
||
#eg-wizard-design .ew-body h3 { font-size:15px; margin:0 0 10px; font-weight:600; }
|
||
#eg-wizard-design .ew-body p { margin:0 0 14px; font-size:13px; }
|
||
#eg-wizard-design .ew-muted { color:var(--ew-muted); }
|
||
#eg-wizard-design .ew-small { font-size:11px !important; }
|
||
#eg-wizard-design .ew-box { padding:14px 16px; border:1px solid var(--ew-line); border-radius:6px; margin:14px 0; background:var(--ew-bg); }
|
||
#eg-wizard-design .ew-box-top { display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap; margin-bottom:7px; }
|
||
#eg-wizard-design .ew-chip { display:inline-block; color:var(--ew-good); background:var(--ew-soft); font-size:11px; padding:2px 7px; border-radius:4px; }
|
||
#eg-wizard-design .ew-path { display:block; font-size:12px; color:var(--ew-muted); overflow-wrap:anywhere; }
|
||
#eg-wizard-design .ew-note { display:flex; align-items:flex-start; gap:9px; padding:12px; background:var(--ew-wash); color:var(--ew-blue); border-radius:5px; font-size:12px; margin-top:14px; }
|
||
#eg-wizard-design .ew-note svg { flex-shrink:0; margin-top:2px; }
|
||
#eg-wizard-design .ew-list { padding:0; margin:0; list-style:none; }
|
||
#eg-wizard-design .ew-list li { display:flex; justify-content:space-between; gap:12px; padding:9px 0; font-size:12px; border-bottom:1px solid var(--ew-line); }
|
||
#eg-wizard-design .ew-list li:last-child { border:0; }
|
||
#eg-wizard-design .ew-good { color:var(--ew-good); }
|
||
#eg-wizard-design .ew-bad { color:var(--ew-bad); }
|
||
#eg-wizard-design .ew-status { font-size:11px; white-space:nowrap; }
|
||
#eg-wizard-design .ew-field { display:grid; gap:6px; font-size:12px; margin:0 0 16px; }
|
||
#eg-wizard-design .ew-field input { width:100%; border:1px solid var(--ew-line); border-radius:5px; padding:9px 10px; background:var(--ew-bg); color:var(--ew-ink); font:12px/1.5 'Segoe UI','Malgun Gothic',sans-serif; }
|
||
#eg-wizard-design .ew-choice { display:flex; align-items:flex-start; gap:8px; padding:9px 0; font-size:12px; }
|
||
#eg-wizard-design .ew-choice input { accent-color:var(--ew-blue); margin:3px 0 0; flex-shrink:0; }
|
||
#eg-wizard-design .ew-choice span { display:block; }
|
||
#eg-wizard-design .ew-choice small { display:block; color:var(--ew-muted); font-size:11px; margin-top:2px; }
|
||
#eg-wizard-design .ew-rule { height:1px; background:var(--ew-line); margin:14px 0; }
|
||
#eg-wizard-design .ew-summary { display:grid; grid-template-columns:88px minmax(0,1fr); gap:10px 14px; font-size:12px; margin:0; }
|
||
#eg-wizard-design .ew-summary dt { color:var(--ew-muted); }
|
||
#eg-wizard-design .ew-summary dd { margin:0; }
|
||
#eg-wizard-design .ew-progress { background:var(--ew-soft); height:8px; border-radius:4px; overflow:hidden; margin:18px 0 7px; }
|
||
#eg-wizard-design .ew-progress span { display:block; background:var(--ew-blue); height:100%; }
|
||
#eg-wizard-design .ew-progress-label { display:flex; justify-content:space-between; gap:12px; color:var(--ew-muted); font-size:12px; margin-bottom:15px; }
|
||
#eg-wizard-design .ew-footer { border-top:1px solid var(--ew-line); background:var(--ew-soft); padding:14px 18px; border-radius:0 0 9px 9px; display:flex; justify-content:space-between; align-items:center; gap:10px; flex-wrap:wrap; }
|
||
#eg-wizard-design .ew-footer-label { color:var(--ew-muted); font-size:11px; }
|
||
#eg-wizard-design .ew-actions { display:flex; gap:7px; flex-wrap:wrap; margin-left:auto; }
|
||
#eg-wizard-design .ew-symbol { display:grid; place-items:center; width:42px; height:42px; border-radius:50%; background:var(--ew-wash); color:var(--ew-blue); font-size:23px; margin:0 0 15px; }
|
||
#eg-wizard-design .ew-log { margin-top:16px; color:var(--ew-muted); font-size:11px; }
|
||
#eg-wizard-design .ew-log summary { width:fit-content; }
|
||
#eg-wizard-design .ew-log pre { white-space:pre-wrap; overflow-wrap:anywhere; font:11px/1.7 'Segoe UI','Malgun Gothic',sans-serif; }
|
||
#eg-wizard-design .ew-confirm { background:var(--ew-bg); border:1px solid var(--ew-line); border-radius:6px; padding:16px; margin-top:16px; }
|
||
#eg-wizard-design .ew-confirm .ew-actions { margin-top:12px; }
|
||
#eg-wizard-design .ew-compact .ew-layout { display:block; }
|
||
#eg-wizard-design .ew-compact .ew-side { display:none; }
|
||
#eg-wizard-design .ew-compact .ew-page-heading { padding-left:30px; padding-right:30px; background:var(--ew-soft); }
|
||
#eg-wizard-design .ew-compact .ew-body { max-width:610px; padding:24px 30px; margin:auto; }
|
||
#eg-wizard-design .ew-caption { color:var(--ew-muted); font-size:11px; margin:10px 0 0; }
|
||
@media(max-width:580px) { #eg-wizard-design .ew-stage { min-height:850px; } #eg-wizard-design .ew-layout { display:block; } #eg-wizard-design .ew-side { padding:12px 16px; border-right:0; border-bottom:1px solid var(--ew-line); } #eg-wizard-design .ew-side-brand,#eg-wizard-design .ew-side-sub { display:none; } #eg-wizard-design .ew-steps { display:flex; gap:7px; justify-content:space-between; margin:0; } #eg-wizard-design .ew-steps li { flex-direction:column; gap:5px; font-size:11px; } #eg-wizard-design .ew-page-heading,#eg-wizard-design .ew-compact .ew-page-heading { padding:18px; } #eg-wizard-design .ew-body,#eg-wizard-design .ew-compact .ew-body { padding:18px; } #eg-wizard-design .ew-preview { padding-right:0; padding-top:55px; } #eg-wizard-design .ew-title { padding:10px 14px; } #eg-wizard-design .ew-summary { grid-template-columns:70px minmax(0,1fr); } }
|
||
@media(pointer:coarse) { #eg-wizard-design button,#eg-wizard-design select,#eg-wizard-design .ew-choice { min-height:44px; } #eg-wizard-design .ew-field input { font-size:16px; } }
|
||
</style>
|
||
<div id="eg-wizard-design" class="viz-carousel viz-dotted-background" aria-label="EG-BIM 설치 마법사 재디자인" data-previous-label="이전 디자인" data-next-label="다음 디자인">
|
||
<section data-variant="진행 안내형" class="ew-stage" aria-label="진행 안내형 설치 마법사"><div id="ew-guided-tools" class="ew-preview"></div><div id="ew-guided" class="ew-app" aria-label="진행 안내형"></div></section>
|
||
<section data-variant="표준 마법사형" class="ew-stage" aria-label="표준 마법사형 설치 마법사" hidden><div id="ew-standard-tools" class="ew-preview"></div><div id="ew-standard" class="ew-app ew-compact" aria-label="표준 마법사형"></div></section>
|
||
</div>
|
||
<script>
|
||
(() => {
|
||
const root=document.getElementById('eg-wizard-design');
|
||
const escape=v=>String(v).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
||
const modes={new:'신규 설치',upgrade:'기존 버전 전환',patch:'버전 패치',repair:'설치 복구',remove:'제거'};
|
||
const scenarios={normal:'정상 완료',backupFail:'백업 실패',applyFail:'설치 실패',reboot:'재부팅 필요',locked:'실행 중인 앱'};
|
||
const actions={new:'설치',upgrade:'업데이트',patch:'패치 적용',repair:'복구',remove:'제거'};
|
||
const basePath='C:\\Program Files\\Baron\\EG-BIM', legacyPath='D:\\Baron\\EG-BIM';
|
||
const defaults=()=>({mode:'upgrade',scenario:'normal',page:'welcome',agreed:false,path:basePath,resources:true,shortcut:true,removeConfirmed:false,launch:true,restart:false,confirmCancel:false,cancelled:false,error:'',closed:false});
|
||
function sequence(s) { return s.mode==='new'?['welcome','license','options','review','prepare','apply','finish']:['welcome','review','prepare','apply','finish']; }
|
||
function normalize(input) { const s=defaults(); if(!input||typeof input!=='object')return s; for(const key of Object.keys(s)){if(typeof input[key]===typeof s[key])s[key]=input[key];} if(!modes[s.mode])s.mode='upgrade';if(!scenarios[s.scenario])s.scenario='normal';if(![...sequence(s),'failed','cancelled'].includes(s.page))s.page='welcome'; if(s.scenario==='backupFail'&&!['upgrade','patch'].includes(s.mode))s.scenario='normal';return s; }
|
||
const saved=window.openai?.widgetState?.privateContent?.wizards||{};
|
||
const states={'ew-guided':normalize(saved['ew-guided']),'ew-standard':normalize(saved['ew-standard'])};
|
||
function next(s) {
|
||
s.error='';
|
||
if(s.page==='license'&&!s.agreed){s.error='사용권 계약에 동의해야 다음 단계로 이동할 수 있습니다.';return;}
|
||
if(s.page==='options'&&!/^[a-zA-Z]:\\[^<>:"|?*\r\n]+$/.test(s.path)){s.error='드라이브를 포함한 설치 경로를 입력해 주세요. 예: C:\\Program Files\\Baron\\EG-BIM';return;}
|
||
if(s.page==='review'&&s.mode==='remove'&&!s.removeConfirmed){s.error='제거할 항목을 확인하고 동의해 주세요.';return;}
|
||
const seq=sequence(s),index=seq.indexOf(s.page); if(index>=0&&index<seq.length-1)s.page=seq[index+1];
|
||
}
|
||
function simulate(s) {
|
||
if(s.confirmCancel)return;
|
||
if(s.page==='prepare') {
|
||
if(s.scenario==='locked'){s.error='EG-BIM에서 도면을 저장하고 종료한 후 다시 확인해 주세요.';return;}
|
||
s.page=s.scenario==='backupFail'?'failed':'apply';
|
||
} else if(s.page==='apply')s.page=s.cancelled||s.scenario==='applyFail'?'failed':'finish';
|
||
}
|
||
function row(label,value,tone='') {return `<li><span>${label}</span><span class="ew-status ${tone}">${value}</span></li>`;}
|
||
function note(text,icon='shield-check') {return `<div class="ew-note"><i data-lucide="${icon}" aria-hidden="true"></i><span>${text}</span></div>`;}
|
||
function choice(label,key,checked,sub='',disabled=false) {return `<label class="ew-choice"><input type="checkbox" data-value="${key}" ${checked?'checked':''} ${disabled?'disabled':''}><span>${label}${sub?`<small>${sub}</small>`:''}</span></label>`;}
|
||
function title(s) {
|
||
const a=actions[s.mode];
|
||
return {welcome:[s.mode==='new'?'EG-BIM 설치를 시작합니다':s.mode==='upgrade'?'기존 EG-BIM을 업데이트합니다':s.mode==='patch'?'새 버전의 변경 사항을 적용합니다':s.mode==='repair'?'EG-BIM 설치를 복구합니다':'EG-BIM을 제거합니다','계속하려면 내용을 확인하고 다음을 선택하세요.'],license:['사용권 계약','설치하기 전에 사용권 계약을 확인해 주세요.'],options:['설치 위치 및 옵션','설치할 위치와 추가 항목을 선택하세요.'],review:[`${a} 준비가 되었습니다`,'아래 내용을 확인하세요. 이전 단계로 돌아가 선택을 바꿀 수 있습니다.'],prepare:['설치 환경을 준비하고 있습니다','작업을 저장하고 실행 중인 EG-BIM을 종료해 주세요.'],apply:[s.cancelled?'취소 요청을 처리하고 있습니다':`${a} 작업을 진행하고 있습니다`,s.cancelled?'안전한 중단 지점과 현재 설치 상태를 확인합니다.':'작업이 끝날 때까지 PC를 끄지 마세요.'],finish:[s.scenario==='reboot'?'완료하려면 PC를 다시 시작해야 합니다':`${a} 작업이 완료되었습니다`,s.scenario==='reboot'?'열려 있는 작업을 저장한 후 다시 시작해 주세요.':'아래 내용을 확인하고 마침을 선택하세요.'],failed:[s.scenario==='backupFail'?'설정 백업을 완료하지 못했습니다':s.cancelled?'작업을 중단했습니다':'설치를 완료하지 못했습니다',s.scenario==='backupFail'?'기존 제품을 변경하지 않았습니다.':'현재 상태를 확인한 후 복구 절차를 진행해야 합니다.'],cancelled:['설치를 취소했습니다','프로그램을 변경하기 전에 종료했습니다.']}[s.page];
|
||
}
|
||
function body(s) {
|
||
const a=actions[s.mode], existing=s.mode!=='new', backup=['upgrade','patch'].includes(s.mode), path=existing?legacyPath:s.path;
|
||
if(s.page==='welcome')return `<div class="ew-symbol"><i data-lucide="${s.mode==='remove'?'package-minus':s.mode==='repair'?'wrench':'package-check'}" aria-hidden="true"></i></div><h3>${s.mode==='new'?'설계에 필요한 도구를 준비하세요.':s.mode==='upgrade'?'작업 환경은 유지하고, 프로그램은 새롭게.':s.mode==='patch'?'설치된 구성은 그대로 유지합니다.':s.mode==='repair'?'프로그램 파일과 설치 정보를 복구합니다.':'프로그램과 설치 항목을 제거합니다.'}</h3><p class="ew-muted">${s.mode==='remove'?'개인 도면, 사용자 설정과 보관된 백업은 유지합니다.':s.mode==='new'?'마법사의 안내에 따라 설치 위치와 옵션을 선택할 수 있습니다.':'작업 중인 도면을 저장한 후 진행해 주세요.'}</p><div class="ew-box"><div class="ew-box-top"><strong>EG-BIM</strong><span class="ew-chip">${existing?'기존 설치 확인':'Windows · x64'}</span></div><span class="ew-path">${escape(path)}</span><span class="ew-small ew-muted">${existing?'기존 설치 위치를 그대로 사용합니다.':'기본 설치 위치 · 다음 단계에서 변경 가능'}</span></div>${note(backup?'설정 백업을 확인한 후 프로그램 변경을 시작합니다.':s.mode==='remove'?'타사 CAD 연결과 사용자 데이터는 삭제 대상에서 제외합니다.':'시스템 변경이 필요한 경우 Windows가 관리자 권한을 요청합니다.')}`;
|
||
if(s.page==='license')return `<div class="ew-box"><h3>EG-BIM 소프트웨어 사용권 계약</h3><p class="ew-muted">설치 화면 검토용 약관 자리표시자입니다.</p><p class="ew-small ew-muted">실제 설치 파일에는 제품 담당자가 승인한 약관 전문과 버전을 표시합니다. 이 시안의 선택은 법적 계약 동의나 실제 설치를 수행하지 않습니다.</p></div>${choice('사용권 계약에 동의합니다.','agreed',s.agreed)}${note('동의 여부는 설치 시작 전까지 변경할 수 있습니다.','info')}`;
|
||
if(s.page==='options')return `<label class="ew-field">설치 위치<input data-path aria-label="설치 위치" value="${escape(s.path)}" spellcheck="false"></label><h3>설치 구성</h3>${choice('EG-BIM 프로그램','core',true,'필수 구성요소',true)}${choice('추가 리소스','resources',s.resources,'기능 선택 예시 · 실제 리소스 목록은 별도 확정')}<div class="ew-rule"></div>${choice('바탕 화면에 바로가기 만들기','shortcut',s.shortcut)}<p class="ew-small ew-muted">기존 CAD 파일 연결은 자동으로 변경하지 않습니다.</p>`;
|
||
if(s.page==='review')return `<dl class="ew-summary"><dt>작업</dt><dd>${modes[s.mode]}</dd><dt>${s.mode==='remove'?'제거 위치':'설치 위치'}</dt><dd>${escape(path)}${existing&&s.mode!=='remove'?' · 유지':''}</dd><dt>설치 구성</dt><dd>${s.mode==='remove'?'현재 설치된 프로그램 제거':existing?'현재 설치된 기능 유지':s.resources?'프로그램 + 추가 리소스':'프로그램'}</dd><dt>사용자 데이터</dt><dd>${backup?'설정·CUI·추가 리소스 백업 후 호환 설정 복원':s.mode==='remove'?'개인 도면·설정·백업 유지':'기존 데이터 유지'}</dd>${s.mode==='new'?`<dt>바로가기</dt><dd>${s.shortcut?'바탕 화면에 생성':'생성 안 함'}</dd>`:''}<dt>필수 구성</dt><dd>${s.mode==='remove'?'공유 런타임 유지':'필요한 런타임만 준비'}</dd></dl>${s.mode==='remove'?choice('프로그램을 제거하고 개인 데이터는 유지합니다.','removeConfirmed',s.removeConfirmed):note(backup?'파일 확보와 백업 검증에 실패하면 기존 제품을 제거하지 않습니다.':'설치 전 패키지와 저장 공간을 다시 확인합니다.')}<details class="ew-log"><summary class="cursor-interaction">예정 작업 자세히 보기</summary><p>환경 검사 → 파일 검증 → ${backup?'앱 종료 확인 · 설정 백업 → ':''}${a} → 상태 확인${backup?' · 설정 복원':''}</p></details>`;
|
||
if(s.page==='prepare')return `<ul class="ew-list">${row('지원 환경 · 저장 공간','확인 완료','ew-good')}${row('설치 파일 · 서명 · 무결성','확인 완료','ew-good')}${row('실행 중인 프로그램',s.scenario==='locked'?'EG-BIM 실행 중':'종료 확인',s.scenario==='locked'?'ew-bad':'ew-good')}${backup?row('사용자 설정 백업',s.scenario==='locked'?'대기':'검사 중'):row('실행 계획 준비','준비 중')}</ul>${s.scenario==='locked'?`${note('도면을 직접 저장하고 EG-BIM을 종료해 주세요. 강제 종료하지 않습니다.','info')}<button type="button" class="ew-button cursor-interaction" data-action="recheck" style="margin-top:12px">다시 확인</button>`:note(backup?'백업 위치: D:\\EG-BIM-Backup\\시도-001 (예시)':'현재까지 프로그램 파일은 변경하지 않았습니다.')}<p class="ew-small ew-muted" style="margin-top:16px">시안 진행은 창 위의 ‘작업 진행’으로 확인할 수 있습니다.</p>`;
|
||
if(s.page==='apply')return `<h3>${s.cancelled?'안전한 중단 지점 확인 중':s.mode==='remove'?'등록된 프로그램 파일 제거 중':'프로그램 파일 적용 중'}</h3><div class="ew-progress" role="progressbar" aria-label="진행률 예시" aria-valuemin="0" aria-valuemax="100" aria-valuenow="64"><span style="width:64%"></span></div><div class="ew-progress-label"><span>${s.cancelled?'취소 요청됨':'현재 작업 진행률'}</span><span>64%</span></div><ul class="ew-list">${row('환경 및 설치 파일 확인','완료','ew-good')}${backup?row('사용자 설정 백업 검증','완료','ew-good'):''}${row(a,s.cancelled?'중단 요청 처리 중':'진행 중')}${row('설치 상태 확인','대기')}</ul><details class="ew-log"><summary class="cursor-interaction">작업 내역 보기</summary><pre>시도: DEMO-001\n환경 검사: 완료\n패키지 검증: 완료\n${backup?'백업 검증: 완료\n':''}작업 상태: ${s.cancelled?'취소 처리 중':'적용 중'}\n이 내역은 시안용 예시입니다.</pre></details>`;
|
||
if(s.page==='failed')return `<div class="ew-symbol">!</div><h3>${s.scenario==='backupFail'?'백업 저장 위치를 확인해 주세요.':'진단 기록을 보관해 주세요.'}</h3><p class="ew-muted">${s.scenario==='backupFail'?'백업 위치의 공간 또는 쓰기 권한을 확인한 후 다시 검사할 수 있습니다.':'현재 설치 상태가 확인되지 않았습니다. 설치 파일을 다시 실행하거나 전체 설치로 덮어쓰기 전에 복구 상태를 확인해야 합니다.'}</p><ul class="ew-list">${row('프로그램 상태',s.scenario==='backupFail'?'기존 상태 유지':'확인 필요',s.scenario==='backupFail'?'ew-good':'ew-bad')}${row('백업',backup?(s.scenario==='backupFail'?'검증되지 않음':'보관됨'):'해당 없음')}${row('다음 조치',s.scenario==='backupFail'?'백업 위치 확인':'진단 및 복구')}</ul><details class="ew-log" open><summary class="cursor-interaction">진단 기록</summary><pre>시도: DEMO-001\n상태: ${s.scenario==='backupFail'?'BackupValidationFailed':s.cancelled?'CancellationStateUncertain':'InstallStateUncertain'}\n로그: 설치 로그 보관 위치 (예시)\n이 시안은 실제 시스템 상태를 조회하지 않습니다.</pre></details>`;
|
||
if(s.page==='cancelled')return `<div class="ew-symbol">−</div><h3>다음에 다시 시작할 수 있습니다.</h3><p class="ew-muted">설치 전 취소되어 기존 프로그램과 사용자 데이터는 유지됩니다.</p>`;
|
||
const reboot=s.scenario==='reboot';
|
||
return `<div class="ew-symbol">${reboot?'↻':'✓'}</div><ul class="ew-list">${row(a,'완료','ew-good')}${backup?row('호환 설정 복원','완료','ew-good'):''}${row('설치 상태',reboot?'재부팅 후 확인':'확인 완료',reboot?'':'ew-good')}</ul>${reboot?`${choice('지금 다시 시작','restart',s.restart,'선택하지 않으면 나중에 직접 재부팅합니다.')}<p class="ew-small ew-muted">시안에서는 실제 재부팅하지 않습니다.</p>`:s.mode!=='remove'?choice('마침 후 EG-BIM 실행','launch',s.launch,'원래 사용자 권한으로 실행'):'<p class="ew-small ew-muted" style="margin-top:15px">개인 도면·사용자 설정·백업은 유지됩니다.</p>'}${backup?note('백업은 유지됩니다. 도면·출력·인증·플러그인을 확인한 후 정리하세요.'):''}${s.closed?'<p class="ew-small ew-muted" role="status" style="margin-top:12px">미리보기를 마쳤습니다. 실제 실행이나 재부팅은 하지 않았습니다.</p>':''}`;
|
||
}
|
||
function persist(id) {window.openai?.setWidgetState?.({modelContent:{design:id==='ew-guided'?'진행 안내형':'표준 마법사형',mode:states[id].mode,page:states[id].page,scenario:states[id].scenario},privateContent:{wizards:states}})?.catch(()=>{});}
|
||
function render(id,focus=false) {
|
||
const s=states[id],app=document.getElementById(id),tools=document.getElementById(id+'-tools');
|
||
tools.innerHTML=`<label>시안 · 설치 상황<select class="cursor-interaction" data-mode aria-label="시안 설치 상황">${Object.entries(modes).map(([k,v])=>`<option value="${k}" ${s.mode===k?'selected':''}>${v}</option>`).join('')}</select></label><label>시험할 상태<select class="cursor-interaction" data-scenario aria-label="시험할 상태">${Object.entries(scenarios).filter(([k])=>k!=='backupFail'||['upgrade','patch'].includes(s.mode)).map(([k,v])=>`<option value="${k}" ${s.scenario===k?'selected':''}>${v}</option>`).join('')}</select></label><button class="ew-button cursor-interaction" data-demo="advance" ${!['prepare','apply'].includes(s.page)||s.confirmCancel?'disabled':''}>작업 진행</button><button class="ew-button cursor-interaction" data-demo="reset">처음부터</button>`;
|
||
tools.querySelector('[data-mode]').addEventListener('change',e=>{states[id]=defaults();states[id].mode=e.target.value;render(id);persist(id);});
|
||
tools.querySelector('[data-scenario]').addEventListener('change',e=>{s.scenario=e.target.value;s.page='welcome';s.error='';s.cancelled=false;s.confirmCancel=false;s.closed=false;render(id);persist(id);});
|
||
tools.querySelector('[data-demo=advance]').addEventListener('click',()=>{simulate(s);render(id);persist(id);});
|
||
tools.querySelector('[data-demo=reset]').addEventListener('click',()=>{states[id]={...defaults(),mode:s.mode,scenario:s.scenario};render(id);persist(id);});
|
||
const [heading,sub]=title(s),seq=sequence(s),index=seq.indexOf(s.page);
|
||
const groups=s.mode==='new'?['시작','선택','확인','진행','완료']:['시작','확인','진행','완료'];
|
||
const current=(s.mode==='new'?{welcome:0,license:1,options:1,review:2,prepare:3,apply:3,finish:4,failed:3,cancelled:0}:{welcome:0,review:1,prepare:2,apply:2,finish:3,failed:2,cancelled:0})[s.page];
|
||
const busy=['prepare','apply'].includes(s.page),end=['finish','failed','cancelled'].includes(s.page);
|
||
const button= end?(s.page==='failed'&&s.scenario==='backupFail'?'다시 검사':s.page==='finish'?'마침':'닫기'):s.page==='review'?`${actions[s.mode]} 시작`:busy?s.cancelled?'취소 처리 중…':'진행 중…':'다음';
|
||
app.innerHTML=`<header class="ew-title"><span class="ew-mark">E</span><span>EG-BIM 설치 마법사</span><span class="ew-tag">${modes[s.mode]}</span></header><div class="ew-layout"><aside class="ew-side"><div class="ew-side-brand">EG-BIM</div><div class="ew-side-sub">BARON SOFTWARE</div><ol class="ew-steps">${groups.map((n,i)=>`<li ${i===current?'aria-current="step"':''} class="${i<current?'ew-past':''}"><span class="ew-number">${i<current?'✓':i+1}</span>${n}</li>`).join('')}</ol></aside><main class="ew-main"><header class="ew-page-heading"><h2>${heading}</h2><p>${sub}</p></header><div class="ew-body"><div aria-live="polite">${body(s)}</div>${s.error?`<p class="ew-small ew-bad" role="alert">${escape(s.error)}</p>`:''}${s.confirmCancel?`<section class="ew-confirm" aria-label="취소 확인"><h3>작업을 취소하시겠습니까?</h3><p class="ew-small ew-muted">${s.page==='apply'?'안전한 중단 지점까지 기다린 후 설치 상태를 확인합니다.':'아직 프로그램을 변경하지 않았습니다.'}</p><div class="ew-actions"><button class="ew-button cursor-interaction" data-action="keep">계속 진행</button><button class="ew-button cursor-interaction" data-action="confirm">취소 요청</button></div></section>`:''}</div></main></div><footer class="ew-footer"><span class="ew-footer-label">시안 · 표시 정보는 예시</span><div class="ew-actions"><button class="ew-button cursor-interaction" data-action="back" ${index<=0||busy||end||s.confirmCancel?'disabled':''}>이전</button><button class="ew-button ew-primary cursor-interaction" data-action="next" ${busy||s.confirmCancel||s.page==='license'&&!s.agreed||s.page==='review'&&s.mode==='remove'&&!s.removeConfirmed?'disabled':''}>${button}</button>${!end?`<button class="ew-button cursor-interaction" data-action="cancel" ${s.cancelled||s.confirmCancel?'disabled':''}>취소</button>`:''}</div></footer>`;
|
||
app.querySelector('[data-path]')?.addEventListener('input',e=>{s.path=e.target.value;});
|
||
app.querySelectorAll('[data-value]').forEach(el=>el.addEventListener('change',e=>{s[el.dataset.value]=e.target.checked;render(id);persist(id);app.querySelector(`[data-value="${el.dataset.value}"]`)?.focus({preventScroll:true});}));
|
||
app.querySelector('[data-action=back]').addEventListener('click',()=>{if(index>0&&!busy&&!end){s.page=seq[index-1];s.error='';render(id,true);persist(id);}});
|
||
app.querySelector('[data-action=next]').addEventListener('click',()=>{
|
||
if(s.page==='failed'&&s.scenario==='backupFail'){s.scenario='normal';s.page='prepare';}
|
||
else if(end){s.closed=true;if(s.page!=='finish'){s.page='welcome';s.cancelled=false;s.closed=false;}}
|
||
else next(s);
|
||
render(id,true);persist(id);
|
||
});
|
||
app.querySelector('[data-action=cancel]')?.addEventListener('click',()=>{s.confirmCancel=true;render(id);app.querySelector('[data-action=keep]')?.focus({preventScroll:true});});
|
||
app.querySelector('[data-action=keep]')?.addEventListener('click',()=>{s.confirmCancel=false;render(id,true);});
|
||
app.querySelector('[data-action=confirm]')?.addEventListener('click',()=>{s.confirmCancel=false;if(s.page==='apply')s.cancelled=true;else s.page='cancelled';render(id,true);persist(id);});
|
||
app.querySelector('[data-action=recheck]')?.addEventListener('click',()=>{s.scenario='normal';s.error='';render(id);persist(id);});
|
||
if(globalThis.lucide)lucide.createIcons({attrs:{width:16,height:16}});
|
||
if(focus&&!busy)app.querySelector('[data-action=next]')?.focus({preventScroll:true});
|
||
}
|
||
Object.keys(states).forEach(id=>render(id));
|
||
window.addEventListener('openai:set_globals',e=>{const restored=e.detail?.globals?.widgetState?.privateContent?.wizards;if(restored)Object.keys(states).forEach(id=>{states[id]=normalize(restored[id]);render(id);});});
|
||
if(globalThis.Tweak)Object.keys(states).forEach(id=>{const app=document.getElementById(id),design={radius:9};const tweak=new Tweak({container:app,onChange:()=>{app.style.borderRadius=design.radius+'px';}});tweak.addSlider(design,'radius',{label:'창 모서리',min:0,max:16,unit:'px'});});
|
||
})();
|
||
</script>
|