This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<!doctype html><html lang="ja"><head><meta charset="utf-8" />
|
||||
<style>
|
||||
body{font:14px system-ui;margin:0;padding:16px}
|
||||
.row{display:flex;gap:8px;align-items:center;margin-bottom:8px}
|
||||
ul{list-style:none;padding:0;margin:0}
|
||||
li[data-testid="file-item"]{cursor:pointer;padding:4px 8px;border-radius:4px;background:#f0f0f0;margin-bottom:4px}
|
||||
li[data-testid="file-item"]:hover{background:#dce8ff}
|
||||
pre[data-testid="preview"]{background:#f9f9f9;border:1px solid #ddd;padding:12px;overflow:auto;max-height:50vh;white-space:pre-wrap}
|
||||
table{border-collapse:collapse;width:100%}
|
||||
table th,table td{border:1px solid #ccc;padding:4px 8px;text-align:left}
|
||||
table th{background:#eee}
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="row">
|
||||
<input id="dir" data-testid="dir" value="output" style="flex:1" />
|
||||
<button id="listBtn" data-testid="list">一覧取得</button>
|
||||
<span id="status" data-testid="status"></span>
|
||||
</div>
|
||||
<ul id="files" data-testid="files"></ul>
|
||||
<div id="preview-wrap"></div>
|
||||
<script>
|
||||
let seq=0;const pending=new Map();
|
||||
function call(req){return new Promise((res,rej)=>{const id=++seq;pending.set(id,{res,rej});
|
||||
window.parent.postMessage({...req,id},'*');});}
|
||||
window.addEventListener('message',e=>{const r=e.data;const p=pending.get(r&&r.id);if(!p)return;
|
||||
pending.delete(r.id);r.ok?p.res(r.data):p.rej(new Error(r.error));});
|
||||
const $=id=>document.getElementById(id);
|
||||
|
||||
function renderCsv(text){
|
||||
const rows=text.trim().split('\n').map(r=>r.split(','));
|
||||
const table=document.createElement('table');
|
||||
rows.forEach((cols,i)=>{const tr=document.createElement('tr');
|
||||
cols.forEach(c=>{const cell=document.createElement(i===0?'th':'td');cell.textContent=c;tr.appendChild(cell);});
|
||||
table.appendChild(tr);});
|
||||
return table;
|
||||
}
|
||||
|
||||
async function listDir(){
|
||||
const dir=$('dir').value.trim()||'output';
|
||||
$('status').textContent='取得中…';
|
||||
$('files').innerHTML='';
|
||||
$('preview-wrap').innerHTML='';
|
||||
try{
|
||||
const d=await call({type:'listFiles',dir});
|
||||
const entries=d.entries||[];
|
||||
if(entries.length===0){$('files').innerHTML='<li>(ファイルなし)</li>';}
|
||||
entries.forEach(name=>{
|
||||
const li=document.createElement('li');
|
||||
li.setAttribute('data-testid','file-item');
|
||||
li.textContent=name;
|
||||
li.onclick=()=>openFile(dir,name);
|
||||
$('files').appendChild(li);
|
||||
});
|
||||
$('status').textContent='取得OK';
|
||||
}catch(err){$('status').textContent='エラー:'+err.message;}
|
||||
}
|
||||
|
||||
async function openFile(dir,name){
|
||||
$('status').textContent='読込中…';
|
||||
$('preview-wrap').innerHTML='';
|
||||
try{
|
||||
const path=dir.replace(/\/$/,'')+'/'+name;
|
||||
const d=await call({type:'readFile',path});
|
||||
const content=d.content||'';
|
||||
if(name.endsWith('.csv')){
|
||||
const wrap=document.createElement('div');
|
||||
wrap.setAttribute('data-testid','preview');
|
||||
wrap.appendChild(renderCsv(content));
|
||||
$('preview-wrap').appendChild(wrap);
|
||||
}else{
|
||||
const pre=document.createElement('pre');
|
||||
pre.setAttribute('data-testid','preview');
|
||||
pre.textContent=content;
|
||||
$('preview-wrap').appendChild(pre);
|
||||
}
|
||||
$('status').textContent='読込OK';
|
||||
}catch(err){$('status').textContent='読込失敗:'+err.message;}
|
||||
}
|
||||
|
||||
$('listBtn').onclick=listDir;
|
||||
</script></body></html>
|
||||
Reference in New Issue
Block a user