feat: complete legacy UI and playout parity migration

This commit is contained in:
2026-07-15 13:11:38 +09:00
parent f14800656b
commit 6e0c275fdd
108 changed files with 43738 additions and 560 deletions

View File

@@ -11,7 +11,8 @@
<section class="left-panel" aria-label="종목 및 컷 선택">
<header class="brand-line">
<div class="brand"><span>매일경제TV</span><strong>VRi</strong></div>
<div class="connection-state" aria-label="Tornado2 연결 상태">미연결</div>
<div class="connection-state" id="playout-connection-state"
aria-label="Tornado2 연결 상태">미연결</div>
</header>
<div class="search-line">
@@ -23,10 +24,16 @@
<div id="stock-results" class="stock-results" role="listbox" aria-label="종목명"></div>
<div class="manual-actions" aria-label="수동 입력">
<button type="button" disabled>주요매출 구성</button>
<button type="button" disabled>성장성 지표</button>
<button type="button" disabled>매출액</button>
<button type="button" disabled>영업이익</button>
<button type="button" data-manual-screen="revenue-composition">주요매출 구성</button>
<button type="button" data-manual-screen="growth-metrics">성장성 지표</button>
<button type="button" data-manual-screen="sales">매출액</button>
<button type="button" data-manual-screen="operating-profit">영업이익</button>
</div>
<div class="manual-list-actions" aria-label="수동 송출 목록" hidden>
<button type="button" data-manual-list-screen="individual">개인 순매도</button>
<button type="button" data-manual-list-screen="foreign">외국인 순매도</button>
<button type="button" data-manual-list-screen="institution">기관 순매도</button>
<button type="button" data-manual-list-screen="vi">VI 발동</button>
</div>
<div id="cut-list" class="cut-list" role="listbox" aria-label="종목 컷" aria-multiselectable="true"></div>
@@ -34,74 +41,195 @@
</section>
<section class="catalog-panel" aria-label="분류별 그래픽">
<nav class="market-tabs" aria-label="시장 분류">
<button class="active" type="button" disabled>해외</button>
<button type="button" disabled>환율</button>
<button type="button" disabled>지수</button>
<button type="button" disabled>코스피</button>
<button type="button" disabled>코스닥</button>
<button type="button" disabled>비교</button>
<button type="button" disabled>테마</button>
<button type="button" disabled>해외종목</button>
<button type="button" disabled>전문가</button>
<button type="button" disabled>정지</button>
<nav id="market-tabs" class="market-tabs" aria-label="시장 분류">
<button class="active" type="button" draggable="true" data-tab-id="overseas">해외</button>
<button type="button" draggable="true" data-tab-id="exchange">환율</button>
<button type="button" draggable="true" data-tab-id="index">지수</button>
<button type="button" draggable="true" data-tab-id="kospiIndustry">코스피</button>
<button type="button" draggable="true" data-tab-id="kosdaqIndustry">코스닥</button>
<button type="button" draggable="true" data-tab-id="comparison">비교</button>
<button type="button" draggable="true" data-tab-id="theme">테마</button>
<button type="button" draggable="true" data-tab-id="overseasStocks">해외종목</button>
<button type="button" draggable="true" data-tab-id="expert">전문가</button>
<button type="button" draggable="true" data-tab-id="tradingHalt">정지</button>
</nav>
<label class="expand-line"><input type="checkbox" checked disabled> Expand</label>
<label class="expand-line"><input id="catalog-expand-all" type="checkbox" checked> Expand</label>
<div class="category-title">Category</div>
<div class="category-tree" aria-label="원본 카테고리">
<div class="tree-root"><strong>[1열판기본]</strong></div>
<div class="tree-item">▸ 다우</div>
<div class="tree-item">▸ 나스닥</div>
<div class="tree-item">▸ S&amp;P</div>
<div class="tree-item">▸ 독일</div>
<div class="tree-item">▸ 영국</div>
<div class="tree-item">▸ 프랑스</div>
<div class="tree-item">▸ 니케이</div>
<div class="tree-item">▸ 중국 상해</div>
<div class="tree-item">▸ 홍콩 항셍</div>
<div class="tree-item">▸ 대만 가권</div>
<div class="tree-item">▸ 싱가포르 지수</div>
<div class="tree-item">▸ 필리핀 지수</div>
<div class="tree-item">▸ 말레이시아 지수</div>
<div class="tree-root second"><strong>[2열판-]</strong></div>
<div class="tree-item">▸ 공산품 [원면, 목화(면화)]</div>
<div class="tree-item">▸ 원자재 [국제 금, 국제 은]</div>
</div>
<div id="category-tree" class="category-tree" aria-label="원본 카테고리"></div>
</section>
<section class="playlist-panel" aria-label="플레이리스트">
<div class="playlist-toolbar">
<label><input type="checkbox" checked disabled> 전체</label>
<label><input type="checkbox" checked disabled> 5일선</label>
<label><input type="checkbox" checked disabled> 20일선</label>
<button type="button" disabled></button>
<button type="button" disabled></button>
<label><input id="playlist-enable-all" type="checkbox" checked disabled> 전체</label>
<label><input id="moving-average-5" type="checkbox" checked> 5일선</label>
<label><input id="moving-average-20" type="checkbox" checked> 20일선</label>
<button id="playlist-move-up" type="button" disabled aria-label="선택 행 위로 이동"></button>
<button id="playlist-move-down" type="button" disabled aria-label="선택 행 아래로 이동"></button>
<span class="toolbar-spacer"></span>
<label><input type="checkbox" disabled> 배경없음(F3)</label>
<button type="button" disabled>배경파일(F2)</button>
<input class="background-name" value="기본.vrv" readonly>
<button type="button" disabled>DB 저장</button>
<button type="button" disabled>DB 불러오기</button>
<button type="button" disabled>선택삭제</button>
<button type="button" disabled>전체삭제</button>
<label><input id="playout-background-none" type="checkbox" disabled> 배경없음(F3)</label>
<button id="playout-background-file" type="button" disabled>배경파일(F2)</button>
<input id="playout-background-name" class="background-name" value="배경없음" readonly>
<label class="fade-control" for="playout-fade-duration" hidden>효과</label>
<select id="playout-fade-duration" disabled aria-label="장면 효과 시간" hidden>
<option value="0">1</option><option value="1">2</option>
<option value="2">3</option><option value="3">4</option>
<option value="4">5</option><option value="5">6</option>
<option value="6">7</option><option value="7">8</option>
<option value="8">9</option><option value="9">10</option>
<option value="10">11</option><option value="11">12</option>
<option value="12">13</option><option value="13">14</option>
<option value="14">15</option><option value="15">16</option>
<option value="16">17</option><option value="17">18</option>
<option value="18">19</option><option value="19">20</option>
</select>
<button id="db-save-button" type="button" disabled>DB 저장</button>
<button id="db-load-button" type="button" disabled>DB 불러오기</button>
<button id="playlist-delete-selected" type="button" disabled>선택삭제(DEL)</button>
<button id="playlist-delete-all" type="button" disabled>전체삭제</button>
</div>
<div id="playlist-drop-zone" class="playlist-grid">
<div class="playlist-header playlist-row">
<div>송출</div><div>종류</div><div>종목</div><div>컷파일</div><div>세부사항</div><div>Page</div>
</div>
<div id="playlist-rows" class="playlist-rows"></div>
<div id="playlist-rows" class="playlist-rows" role="listbox" aria-label="송출 목록" aria-multiselectable="true"></div>
</div>
<div class="playout-actions">
<button class="take-in" type="button" disabled> TAKE IN [F8]</button>
<button class="next" type="button" disabled> NEXT</button>
<button class="take-out" type="button" disabled>TAKE OUT[Esc]</button>
<button id="playout-prepare" class="prepare" type="button" disabled hidden
aria-hidden="true">PREPARE</button>
<button id="playout-take-in" class="take-in" type="button" disabled>● TAKE IN [F8]</button>
<button id="playout-next" class="next" type="button" disabled> NEXT</button>
<button id="playout-take-out" class="take-out" type="button" disabled>✖ TAKE OUT[Esc]</button>
</div>
<div class="playout-status">원본 호환 UI 기준선 · 송출 연결 안 함</div>
<div id="playout-status" class="playout-status" aria-live="polite">송출 상태를 확인하고 있습니다.</div>
</section>
</main>
<div id="named-playlist-modal" class="named-playlist-backdrop" hidden>
<section class="named-playlist-dialog" role="dialog" aria-modal="true"
aria-labelledby="named-playlist-title">
<header>
<h2 id="named-playlist-title">DB 재생목록</h2>
<button id="named-playlist-close" type="button" aria-label="닫기">×</button>
</header>
<div id="named-playlist-status" class="named-playlist-status" aria-live="polite"></div>
<div class="named-playlist-body">
<div id="named-playlist-definitions" class="named-playlist-definitions"
role="listbox" aria-label="저장된 DB 재생목록"></div>
<section class="named-playlist-create" aria-labelledby="named-playlist-create-title">
<h3 id="named-playlist-create-title">새 재생목록</h3>
<label for="named-playlist-new-title">이름</label>
<input id="named-playlist-new-title" maxlength="128" autocomplete="off"
spellcheck="false">
<button id="named-playlist-create-button" type="button" disabled>새로 만들기</button>
<p>DB 쓰기는 이 버튼 또는 저장·삭제 버튼을 누른 경우에만 한 번 실행됩니다.</p>
</section>
</div>
<footer>
<button id="named-playlist-delete-button" type="button" disabled>선택 삭제</button>
<span class="named-playlist-footer-spacer"></span>
<button id="named-playlist-cancel-button" type="button">취소</button>
<button id="named-playlist-confirm-button" type="button" disabled>확인</button>
</footer>
</section>
</div>
<div id="manual-financial-modal" class="manual-financial-backdrop" hidden>
<section class="manual-financial-dialog" role="dialog" aria-modal="true"
aria-labelledby="manual-financial-title">
<header>
<h2 id="manual-financial-title">수동 재무 입력</h2>
<button id="manual-financial-close" type="button" aria-label="닫기">×</button>
</header>
<div id="manual-financial-workspace" class="manual-financial-workspace"></div>
</section>
</div>
<div id="manual-list-modal" class="manual-list-backdrop" hidden>
<section class="manual-list-dialog" role="dialog" aria-modal="true"
aria-labelledby="manual-list-title">
<header>
<h2 id="manual-list-title">수동 송출 목록</h2>
<button id="manual-list-close" type="button" aria-label="닫기">×</button>
</header>
<div id="manual-list-workspace" class="manual-list-workspace"></div>
</section>
</div>
<div id="operator-catalog-modal" class="operator-catalog-backdrop" hidden>
<section class="operator-catalog-dialog" role="dialog" aria-modal="true"
aria-labelledby="operator-catalog-title">
<header>
<h2 id="operator-catalog-title">ThemeA / EList 관리</h2>
<button id="operator-catalog-close" type="button" aria-label="닫기">×</button>
</header>
<div id="operator-catalog-status" class="operator-catalog-status"
aria-live="polite"></div>
<div class="operator-catalog-toolbar">
<button id="operator-catalog-theme-tab" type="button">ThemeA</button>
<button id="operator-catalog-expert-tab" type="button">EList</button>
<input id="operator-catalog-query" type="search" maxlength="64"
autocomplete="off" placeholder="이름 검색">
<select id="operator-catalog-session" aria-label="NXT 세션">
<option value="preMarket">NXT 장전</option>
<option value="afterMarket">NXT 시간외</option>
</select>
<button id="operator-catalog-search" type="button">검색</button>
</div>
<div class="operator-catalog-body">
<section class="operator-catalog-list-panel" aria-labelledby="operator-catalog-list-title">
<div class="operator-catalog-panel-header">
<h3 id="operator-catalog-list-title">DB 목록</h3>
<select id="operator-catalog-new-market" aria-label="새 ThemeA 시장">
<option value="krx">KRX</option>
<option value="nxt">NXT</option>
</select>
<button id="operator-catalog-new" type="button">새 항목</button>
</div>
<div id="operator-catalog-results" class="operator-catalog-results"
role="listbox" aria-label="ThemeA EList 목록"></div>
</section>
<section id="operator-catalog-editor" class="operator-catalog-editor"
aria-labelledby="operator-catalog-editor-title">
<div class="operator-catalog-panel-header">
<h3 id="operator-catalog-editor-title">추가·편집</h3>
<span id="operator-catalog-code" class="operator-catalog-code"></span>
</div>
<label class="operator-catalog-name-field">
<span id="operator-catalog-name-label">이름</span>
<input id="operator-catalog-name" maxlength="128" autocomplete="off">
</label>
<div class="operator-catalog-stock-search">
<input id="operator-catalog-stock-query" type="search" maxlength="64"
autocomplete="off" placeholder="종목명 검색">
<button id="operator-catalog-stock-search" type="button">종목 검색</button>
</div>
<div id="operator-catalog-stock-results" class="operator-catalog-stock-results"
role="listbox" aria-label="stock master 검색 결과"></div>
<div class="operator-catalog-add-line">
<label id="operator-catalog-amount-label" for="operator-catalog-amount">매수가</label>
<input id="operator-catalog-amount" type="number" min="1" step="1"
inputmode="numeric">
<button id="operator-catalog-add-stock" type="button">선택 종목 추가</button>
</div>
<div class="operator-catalog-draft-header">
<strong>구성 종목</strong>
<span>위·아래 버튼으로 송출 순서를 변경합니다.</span>
</div>
<div id="operator-catalog-draft-rows" class="operator-catalog-draft-rows"
aria-label="ThemeA EList 구성 종목"></div>
<footer class="operator-catalog-editor-actions">
<button id="operator-catalog-delete" type="button">선택 삭제</button>
<span></span>
<button id="operator-catalog-cancel" type="button">편집 취소</button>
<button id="operator-catalog-save" type="button">저장</button>
</footer>
</section>
</div>
</section>
</div>
<div id="legacy-dialog" class="dialog-backdrop" hidden>
<div class="legacy-dialog" role="alertdialog" aria-modal="true" aria-labelledby="legacy-dialog-message">
<div id="legacy-dialog-message"></div>
@@ -110,5 +238,6 @@
</div>
<script src="app.js"></script>
<script src="playout-ui.js"></script>
</body>
</html>