9b015ea745e001ab48af46610af1b7724fd066cc jrobinso Mon Sep 22 16:28:40 2025 -0700 Typo in filepicker text diff --git src/hg/htdocs/admin/filePicker.html src/hg/htdocs/admin/filePicker.html index 41daa88cc4e..34191ca7bdb 100644 --- src/hg/htdocs/admin/filePicker.html +++ src/hg/htdocs/admin/filePicker.html @@ -1,196 +1,196 @@ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>File Manager</title> <link rel="stylesheet" href="../../style/HGStyle.css" type="text/css"> <style> .section-group { border: 2px solid #ccc; /*border-radius: 8px; */ padding: 16px; margin-bottom: 24px; background: #fafafa; } .input-row { display: flex; align-items: center; margin-top: 8px; gap: 16px; } .input-row label { min-width: 100px; } .input-row input[type="url"] { width: 500px; } </style> </head> <body> <section class="section-group" style="text-align: center; margin-bottom: 32px; background: #e3f2fd;"> <h2 style="margin: 0; font-size: 2em;">IGV File Manager</h2> <p style="font-size: 1.1em;"> Please do not close this window, it is necessary to maintain access to the files that you open below. If you close this window, the Genome Browser's IGV track loses access to the files.</p> </section> <section class="section-group"> <div id="message" style="color: red; font-weight: bold; display: none;"> Please select the following files to restore access: <p> <ul id="restoreList"></ul> </p> </div> <h3>Local Files</h3> <p> - Click the "Chose Files" button to select track files in supported formats from your local file system. For + Click the "Choose Files" button to select track files in supported formats from your local file system. For indexed formats both data and index files must be selected. </p> <p> Selected files are loaded directly from your file system to the web browser. <b>No data is transfered to UCSC or any other server, it remains on your local computer</b>. If you make a session shortlink on the Genome Browser, these files will not be included and cannot be loaded by the person that opens the session link. </p> <p> If this window is closed file access is lost, and you must re-open this window with the "Add IGV Tracks" button and re-select the files to restore access. </p> <input type="file" id="fileInput" multiple> <p> <h4>Selected local files:</h4> <ul id="fileList"></ul> </p> </section> <section class="section-group"> <h3>URL</h3> <p> Enter a 'https' URL to an IGV supported track file and its index, if applicable. Data from this URL is loaded directly to your web browser, <b>no data is sent to UCSC or any other server</b>. </p> <p> Note if this is a publicly accessible URL and public data, it is usually easier to load the file as a 'custom track' or 'track hub'. </p> <div class="input-row"> <label for="urlInput">URL</label> <input type="url" id="urlInput"> </div> <div class="input-row"> <label for="indexURLInput">Index URL</label> <input type="url" id="indexURLInput"> </div> <p> <button id="urlButton">Load</button> </p> </section> <script> const fileCache = new Map(); const restoreCache = new Map(); const channel = new BroadcastChannel('igv_file_channel'); document.addEventListener('DOMContentLoaded', () => { channel.postMessage({type: 'filePickerReady'}); document.getElementById('fileInput').addEventListener('change', function (event) { const files = []; for (let file of event.target.files) { const id = `${file.name}_${file.size}`; files.push({id, file}); //value) fileCache.set(id, file); restoreCache.delete(id); refreshFileList(); } event.target.value = ""; channel.postMessage({type: 'selectedFiles', files: files}); }); document.getElementById("urlButton").addEventListener('click', event => { const url = document.getElementById("urlInput").value; if (url) { let indexURL = document.getElementById("indexURLInput").value; if (!indexURL) { if (url.endsWith(".bam")) { indexURL = url + ".bai"; } else if (url.endsWith(".cram")) { indexURL = url + ".crai"; } else if (url.endsWith(".vcf.gz")) { indexURL = url + ".tbi"; } } channel.postMessage({type: 'loadURL', config: {url, indexURL}}); } }); // Respond to messages from the browser page channel.onmessage = function (event) { const {id, type} = event.data; if (type === 'getFile') { const selectedFile = fileCache.get(id); channel.postMessage({type: 'file', id: id, data: selectedFile}); // TODO -- what if selectedFile is undefined? Handle here or in browser? } else if (type === 'removeFile') { fileCache.delete(id); refreshFileList(); } else if (type === 'restoreFiles') { const failed = event.data.files; for (const f of failed) { restoreCache.set(f.id, f.name); } refreshFileList(); } else if (type === 'removedTrack') { // TODO -- might want to remove from restoreCache too const config = event.data.config; if (config.url && config.url.id) { fileCache.delete(config.url.id); restoreCache.delete(config.url.id); } if (config.indexURL && config.indexURL.id) { fileCache.delete(config.indexURL.id); restoreCache.delete(config.indexURL.id); } refreshFileList(); } else if (type === 'ping') { channel.postMessage({type: 'pong', id: window.name}); } channel.postMessage({type: 'pong', id: window.name}); }; }); function refreshFileList() { if (restoreCache.size > 0) { const ul = document.getElementById("restoreList"); ul.innerHTML = ""; for (let name of restoreCache.values()) { ul.innerHTML += `<li>${name}</li>`; } document.getElementById("message").style.display = "block"; } else { document.getElementById("message").style.display = "none"; } const ul = document.getElementById("fileList"); ul.innerHTML = ""; for (let file of fileCache.values()) { ul.innerHTML += `<li>${file.name}</li>`; } } </script> </body> </html>